Solución Tp 01

Tp 1 - Tweets sobre covid-19. Buscando patrones interesantes.

Librerías

library("ggplot2")
library("readr")
library("dplyr")
library("highcharter")
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Highcharts (www.highcharts.com) is a Highsoft software product which is
not free for commercial and Governmental use
library("treemap")
library("modeest")
library("GGally")
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2

Attaching package: 㤼㸱GGally㤼㸲

The following object is masked from 㤼㸱package:dplyr㤼㸲:

    nasa
library("tidyverse")
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
Registered S3 method overwritten by 'httr':
  method         from  
  print.response rmutil
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
v tibble  3.0.1     v stringr 1.4.0
v purrr   0.3.4     v forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x tidyr::expand() masks Matrix::expand()
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
x tidyr::pack()   masks Matrix::pack()
x dplyr::recode() masks arules::recode()
x tidyr::unpack() masks Matrix::unpack()
library("hrbrthemes")
Registering Windows fonts with R
NOTE: Either Arial Narrow or Roboto Condensed fonts are required to use these themes.
      Please use hrbrthemes::import_roboto_condensed() to install Roboto Condensed and
      if Arial Narrow is not on your system, please see https://bit.ly/arialnarrow
library("tidyr")
library("VIM")
Loading required package: colorspace
Loading required package: grid
VIM is ready to use.

Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues

Attaching package: 㤼㸱VIM㤼㸲

The following object is masked from 㤼㸱package:datasets㤼㸲:

    sleep
library("e1071")

Attaching package: 㤼㸱e1071㤼㸲

The following object is masked from 㤼㸱package:modeest㤼㸲:

    skewness
library("mice")

Attaching package: 㤼㸱mice㤼㸲

The following objects are masked from 㤼㸱package:base㤼㸲:

    cbind, rbind
library("mongolite")

library("SnowballC")
library("tm")
Loading required package: NLP

Attaching package: 㤼㸱NLP㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    annotate


Attaching package: 㤼㸱tm㤼㸲

The following object is masked from 㤼㸱package:arules㤼㸲:

    inspect
library("twitteR")

Attaching package: 㤼㸱twitteR㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    id, location
library("syuzhet")

library("tidyverse")
library("lubridate")

Attaching package: 㤼㸱lubridate㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    intersect, setdiff, union

The following objects are masked from 㤼㸱package:arules㤼㸲:

    intersect, setdiff, union

The following objects are masked from 㤼㸱package:base㤼㸲:

    date, intersect, setdiff, union
library("RColorBrewer")
library("infotheo"); # Discretize variable

Attaching package: 㤼㸱infotheo㤼㸲

The following object is masked from 㤼㸱package:arules㤼㸲:

    discretize

Referencia tweets

tweets <- mongo(collection = "tweets_mongo_covid19", db = "DMUBA")

Nombres de columnas

names(tweets$find())
 [1] "user_id"                 "status_id"               "created_at"              "screen_name"            
 [5] "text"                    "source"                  "is_quote"                "is_retweet"             
 [9] "favorite_count"          "retweet_count"           "quote_count"             "reply_count"            
[13] "hashtags"                "symbols"                 "urls_url"                "urls_t_co"              
[17] "urls_expanded_url"       "media_url"               "media_t_co"              "media_expanded_url"     
[21] "media_type"              "ext_media_url"           "ext_media_t_co"          "ext_media_expanded_url" 
[25] "mentions_user_id"        "mentions_screen_name"    "lang"                    "quoted_created_at"      
[29] "retweet_status_id"       "retweet_text"            "retweet_created_at"      "retweet_source"         
[33] "retweet_favorite_count"  "retweet_retweet_count"   "retweet_user_id"         "retweet_screen_name"    
[37] "retweet_name"            "retweet_followers_count" "retweet_friends_count"   "retweet_statuses_count" 
[41] "retweet_verified"        "geo_coords"              "coords_coords"           "bbox_coords"            
[45] "status_url"              "name"                    "location"                "description"            
[49] "protected"               "followers_count"         "friends_count"           "listed_count"           
[53] "statuses_count"          "favourites_count"        "account_created_at"      "verified"               
[57] "profile_banner_url"      "profile_background_url"  "profile_image_url"       "retweet_location"       
[61] "retweet_description"     "quoted_status_id"        "quoted_text"             "quoted_source"          
[65] "quoted_favorite_count"   "quoted_retweet_count"    "quoted_user_id"          "quoted_screen_name"     
[69] "quoted_name"             "quoted_followers_count"  "quoted_friends_count"    "quoted_statuses_count"  
[73] "quoted_location"         "quoted_description"      "quoted_verified"         "url"                    
[77] "place_url"               "place_name"              "place_full_name"         "place_type"             
[81] "country"                 "country_code"            "lat"                     "lng"                    
[85] "display_text_width"      "reply_to_status_id"      "reply_to_user_id"        "reply_to_screen_name"   

Tipos de tweets

t <- mongo(db="DMUBA", collection="tweet_type")
tweets_types <- t$find()
cat("Cantidades de tweets por tipo \n\n")
Cantidades de tweets por tipo 
cat("\t* Tweets: ", nrow(tweets_types), "\n")
    * Tweets:  28907 
cat("\t* Solo RT: ", nrow(tweets_types[tweets_types$is_retweet & !tweets_types$is_quote,]), "\n")
    * Solo RT:  17870 
cat("\t* Solo QT: ", nrow(tweets_types[!tweets_types$is_retweet & tweets_types$is_quote,]), "\n")
    * Solo QT:  1789 
cat("\t* RT y QT: ", nrow(tweets_types[tweets_types$is_retweet & tweets_types$is_quote,]), "\n")
    * RT y QT:  3416 
cat("\t* TW originales: ", nrow(tweets_types[!tweets_types$is_retweet & !tweets_types$is_quote,]), "\n")
    * TW originales:  5832 
tweets_types$tipo <- ""
tweets_types[tweets_types$is_retweet & !tweets_types$is_quote,]$tipo <- "Solo RT"
tweets_types[!tweets_types$is_retweet & tweets_types$is_quote,]$tipo <- "Solo QT"
tweets_types[tweets_types$is_retweet & tweets_types$is_quote,]$tipo <- "RQ y RT"
tweets_types[!tweets_types$is_retweet & !tweets_types$is_quote,]$tipo <- "Original"
# names = c('Solo RT', 'Solo QT', 'RT + QT', 'Original')
# cantidades = c(nrow(tweets_types[tweets_types$is_retweet & !tweets_types$is_quote,]),
#                nrow(tweets_types[!tweets_types$is_retweet & tweets_types$is_quote,]),
#                nrow(tweets_types[tweets_types$is_retweet & tweets_types$is_quote,]),
#                nrow(tweets_types[!tweets_types$is_retweet & !tweets_types$is_quote,])
#               )
#                
grafico_tipos <- data.frame(table(tweets_types$tipo))

# barplot(sort(grafico_tipos$Freq, decreasing=TRUE), legend.text=grafico_tipos$Var1, col=c('red','green','blue','brown'))
# barplot(height=sort(grafico_tipos$Freq, decreasing=TRUE), names=grafico_tipos$Var1, col=rgb(0.2,0.4,0.6,0.6) )

names(grafico_tipos) <- c("Tipos", "Cantidad")

coul <- brewer.pal(5, "Set2") 
barplot(height=sort(grafico_tipos$Cantidad, decreasing=TRUE), names=grafico_tipos$Tipos, col=coul )


# coul <- brewer.pal(5, "Set2") 

# png(filename="tipo_tweet.png", width=1000, bg="white")
ggplot(grafico_tipos, aes(x=reorder(Tipos, Cantidad), y=Cantidad, fill=Tipos)) + 
    geom_bar(stat="identity") +
    scale_fill_brewer(palette="Set2") +
    labs(
      title = "",
      subtitle = "",
      caption = "",
      tag = ""
      ) +
    xlab("") +
    ylab("") +
    theme(plot.title = element_text(hjust = 0.5), 
          axis.text=element_text(size=12),
          axis.text.y = element_text( margin = margin(10, 10, 10, 10)),
          axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),
          legend.text=element_text(size=12)) +
    coord_flip()

# dev.off()

% de Verificados según tipo de tweet


tweets <- mongo(db="DMUBA", collection="tweet_completo_estadisticas")
numericos <- tweets$find()

# Tipos
numericos$Tipo <- ""
numericos[numericos$is_retweet & !numericos$is_quote,]$Tipo <- "Solo RT"
numericos[!numericos$is_retweet & numericos$is_quote,]$Tipo <- "Solo QT"
numericos[numericos$is_retweet & numericos$is_quote,]$Tipo <- "QT y RT"
numericos[!numericos$is_retweet & !numericos$is_quote,]$Tipo <- "Original"

numericos$verificado <- F
numericos[numericos$Tipo == "Solo QT",]$verificado <-  numericos[numericos$Tipo == "Solo QT",]$quoted_verified
numericos[numericos$Tipo == "Original",]$verificado <-  numericos[numericos$Tipo == "Original",]$verified
numericos[numericos$Tipo == "Solo RT",]$verificado <-  numericos[numericos$Tipo == "Solo RT",]$retweet_verified
numericos[numericos$Tipo == "QT y RT",]$verificado <-  numericos[numericos$Tipo == "QT y RT",]$retweet_verified

numericos$verificado_grafico <- ""
numericos[numericos$verificado,]$verificado_grafico <- "Si"
numericos[!numericos$verificado,]$verificado_grafico <- "No"

# png(filename="tipo_x_tweet_grid2.png", width=1000, bg="white")
ggplot(data=numericos, aes(x=verificado_grafico, fill=Tipo)) + 
        scale_fill_brewer(palette="Set2") +
        geom_bar() +
        labs(
          title = "",
          subtitle = "",
          caption = "",
          tag = ""
          ) +
        xlab("") +
        ylab("") +
        theme(plot.title = element_text(hjust = 0.5), 
              axis.text=element_text(size=10),
              axis.text.y = element_text( margin = margin(10, 10, 10, 10)),
              axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),
              legend.text=element_text(size=10),
              aspect.ratio=19/19) +
        facet_wrap(~ Tipo, nrow=2)

# dev.off()
ggplot(data=tweets_types, aes(x=verified, fill=tipo)) + 
  geom_bar() + facet_wrap(~ tipo, nrow=2)

Hay más usuarios verificados en el contenido nuevo. A su vez, hay más verificos en el contenido citado. Eso habla de que un usuario verificado crea un contenido de mayor calidad (Más difundido y novedoso).

Mientras que el usuario difusor y los retweets, si bien aumentan el alcance de los tweets, no tienen una calidad alta.

Tweets según tiempo

t <- mongo(db="DMUBA", collection="fechas")
tweets_fechas <- t$find()
summary(tweets_fecha)
     fecha                           t                                         tc       
 Min.   :2020-04-24 23:52:38   Min.   :2020-04-24 23:52:38   2020-05-02 01:44:00: 1049  
 1st Qu.:2020-05-02 01:46:45   1st Qu.:2020-05-02 01:46:45   2020-05-02 01:40:00: 1043  
 Median :2020-05-04 20:30:15   Median :2020-05-04 20:30:15   2020-05-02 01:45:00: 1041  
 Mean   :2020-05-06 12:24:30   Mean   :2020-05-06 12:24:30   2020-05-02 01:43:00: 1012  
 3rd Qu.:2020-05-10 12:02:52   3rd Qu.:2020-05-10 12:02:52   2020-05-02 01:41:00:  990  
 Max.   :2020-05-15 18:24:13   Max.   :2020-05-15 18:24:13   2020-05-02 01:48:00:  990  
                                                             (Other)            :22782  
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
                                                                                        
 fecha_str.Length  fecha_str.Class  fecha_str.Mode
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 1          -none-     character                  
 [ reached getOption("max.print") -- omitted 28657 rows ]

En un primer intento de graficar, vemos que los datos estan distribuidos de una forma particular. La primera pregunta es ¿Hay alguna fecha que presentó una cantidad anómala de datos?

El 2 de mayo lo es. Sin embargo, no fue un día en el que aconteció alguna cosa. Ni es feriado (1/5), ni fue día de anuncios (25/4).

# plot(tweets_fecha$fecha)
# barplot(table(as.Date(tweets_fecha$fecha)))
f<- data.frame(table(as.Date(tweets_fecha$fecha)))
ggplot(data=f, aes(x=Freq)) + 
  geom_histogram(fill="#69b3a2", color="#e9ecef", alpha=0.9) +
    ggtitle("Bin size = 3") +
    theme_ipsum() +
    theme(
      plot.title = element_text(size=15)
    )

Agrupando en fracciones menos, 5 minutos, vemos que lo que aconteció fue una ventana de captura de datos desigual. Al reducir la ventana de tiempo, vemos que hay una distribución más uniforme. Igualmente sigue planteandose la pregunta, podríamos analizarlo de a minutos, o con diferencias porcentuales, para ver si realmente hya algo ahí.

tweets_fecha$t <- ymd_hms(tweets_fecha$fecha)
tweets_fecha$tc <- cut(tweets_fecha$t, breaks = "5 min")  
cant_5_min <- count(tweets_fecha, tc)
barplot(cant_5_min$n, legend.text=cant_5_min$tc)

## Tweets por fecha
tweets_fecha$t <- ymd_hms(tweets_fecha$fecha)

# Por minuto está más equilibrado)
tweets_fecha$tc <- cut(tweets_fecha$t, breaks = "1 min")  
cant_5_min <- count(tweets_fecha, tc)
barplot(cant_5_min$n)

La variable temporal parece ser arbitraria.

Algo a seguir investigando es la ventana temporal entre: * Fecha creada y fecha de creacion del retweet * Fecha creada y fecha de creacion del quoted

library(ggplot2)
library(dplyr)
library("plotly")

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
library(hrbrthemes)
# tweets_fecha$fecha
tweets_fecha$fecha_str <-  lapply(tweets_fecha$tc, as.character)
b <- as.POSIXlt(strptime(tweets_fecha$tc, format = "%H:%M:%S"))
cant_5_min$fecha <- as.Date(cant_5_min$tc)
cant_5_min$hora <-  format(strptime(cant_5_min$tc, format = "%Y-%m-%d %H:%M:%S"), format="%H:%M:%S")

p <- cant_5_min %>%
  ggplot( aes(x=reorder(hora, hora), y=n, fill=n)) + 
    geom_bar(stat="identity") +
    scale_fill_gradient2(low='red', mid='snow3', high='darkgreen', space='Lab') +
        labs(
          title = "",
          subtitle = "",
          caption = "",
          tag = ""
          ) +
        xlab("") +
        ylab("") +
    theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank()) +
    facet_wrap(~ fecha, nrow=4)

png(filename="tipo_x_tweet.png", width=1000, bg="white")
p
dev.off()
null device 
          1 
# Turn it interactive with ggplotly
p <- ggplotly(p)
argument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NA

p

Texto

tweets_text <- tweets$aggregate('[{
            "$project": { 
                "_id": "$_id",
                "text": "$text"
            }
        }
    ]')
# summary(tweets_text)
# # tweets_text$cantChars <- nchar(tweets_text$text)
# summary(tweets_text)
# Por hay un tweet de 900 char? será por url o cosas así?
boxplot(tweets_text$cantChars)
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -InfError in plot.window(xlim = xlim, ylim = ylim, log = log, yaxs = pars$yaxs) : 
  need finite 'ylim' values

ggplot(tweets_text, aes(x=cantChars)) +
  geom_density(fill="#69b3a2", color="#e9ecef", alpha=0.8) +
  ggtitle("Cantidad de catacteres por tweet") +
  theme_ipsum()

Menos numeros y simbolos


tweets_text.df2$text <- gsub("[[:punct:]]","",tweets_text.df2$text)
tweets_text.df2$text <- gsub("\\w*[0-9]+\\w*\\s*", "",tweets_text.df2$text)
tweets_text.df2$cantChars <- nchar(tweets_text.df2$text)
ggplot(tweets_text.df2, aes(x=cantChars)) +
  geom_density(fill="#69b3a2", color="#e9ecef", alpha=0.8) +
  ggtitle("Sin caracteres especiales y numeros") +
  theme_ipsum()

Hashtags

Cantidad de nulos

tweets_hashes_null <- tweets$find('{"hashtags":{"$elemMatch":{"$in":[null], "$exists":true}}}')
print(nrow(tweets_hashes))
[1] 9636

Preprocesamiento

tweets_count <- mongo(db='DMUBA', collection='tweet_count_hashtags')
tweets_count <- tweets_count$find()
tweets_count$hashtag_2 <- gsub("[[:punct:]]","",tweets_count$hashtag);
tweets_count$hashtag_2 <- gsub("[^[:alnum:][:blank:]?&/\\-]", "", tweets_count$hashtag_2);
tweets_count$hashtag_2 <- iconv(tweets_count$hashtag_2,from="UTF-8",to="ASCII//TRANSLIT");
tweets_count$is_cuarentena_related <- F
for (i in cuarentena_words) {
  tweets_count$is_cuarentena_related <- ifelse(grepl(i, tweets_count$hashtag_2, fixed= T), T, tweets_count$is_cuarentena_related)
}
tweets_count$is_sex_related <- F
for (i in sex_words) {
  tweets_count$is_sex_related <- ifelse(grepl(i, tweets_count$hashtag_2, fixed= T), T, tweets_count$is_sex_related)
}

Top 20 de hashtags no relacionados a cuarentena

head(tweets_count[!tweets_count$is_cuarentena_related & !tweets_count$is_sex_related,] %>% select(2:3), n=20)
NA

Algo que me llamo la atencion: * Cuba * México, bartlett (Ministro mexicano), snte (sindicato de profesores). * Venezuela, proteccionyaccion * AFP, tenía una doble implicación fondo de pensión o agencia de prensa francesa. La primera idea de un fondo de pensiones que pudiese usarse como fondo de emergencia y que generaba polémica era interesante como reaccion al covid. Sin embargo haciendo una segunda búsqueda apartir del campo texto, vemos que un hashtag con repercusión ambigua, toca ambos temas y además fondos de pensión de otros países. Por lo que entrar en el significa mucho tiempo y poca información específica.

TODO: * Hay algo con posibilidad de ser profundizado, que es porque de cada uno, que impacto, quienes lo generaron, que influencia, fueron trending topic, cuantos días? * Argentina vs el resto (Cuba, Mexico, Chile). * Tienen que ver estos hashtags con los trending topic? mismo siendo random, llegamos a obtener parte de esa representatividad de los trending topics?

Perfils de Usuarios:

user_estadisticas <- mongo(db="DMUBA", collection="user_estadisticas")
summary(info_user)
   user_id          screen_name            name           description        followers_count    friends_count   
 Length:25435       Length:25435       Length:25435       Length:25435       Min.   :       0   Min.   :     0  
 Class :character   Class :character   Class :character   Class :character   1st Qu.:      92   1st Qu.:   184  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median :     313   Median :   441  
                                                                             Mean   :   12581   Mean   :  1242  
                                                                             3rd Qu.:     999   3rd Qu.:  1073  
                                                                             Max.   :18609108   Max.   :971277  
  listed_count      statuses_count    favourites_count  account_created_at               verified       user_popularity   
 Min.   :    0.00   Min.   :      1   Min.   :      0   Min.   :2007-02-15 14:03:49   Min.   :0.00001   Length:25435      
 1st Qu.:    0.00   1st Qu.:   2209   1st Qu.:   1116   1st Qu.:2011-05-13 00:01:30   1st Qu.:0.00001   Class :character  
 Median :    1.00   Median :   9386   Median :   5514   Median :2013-12-25 05:01:22   Median :0.00001   Mode  :character  
 Mean   :   51.04   Mean   :  34748   Mean   :  19285   Mean   :2014-08-19 17:22:36   Mean   :0.01444                     
 3rd Qu.:    6.00   3rd Qu.:  31359   3rd Qu.:  19238   3rd Qu.:2018-04-02 03:49:06   3rd Qu.:0.00001                     
 Max.   :57770.00   Max.   :7203370   Max.   :1265094   Max.   :2020-05-15 18:08:33   Max.   :1.00000                     
# User base
info_user <- user_estadisticas$find()
# Con log sin los que tiene 0
data_log <- as.data.frame(apply(info_user[,5:9], 2, log))
# Log con los que tiene 0
info_user[info_user == 0] <- 0.00001
data_log_1 <- as.data.frame(apply(info_user[,5:9], 2, log))

cat("Cantidad de usuarios que han twitteado: ", nrow(info_user))
Cantidad de usuarios que han twitteado:  25435

# ggpairs(data_log)
# ggpairs(info_user[,1:5])

boxplot(info_user[,5:9])


# Con 0's
boxplot(data_log)

# Con 0.0000001's
boxplot(data_log_1)


# 
# info_user$verificado <- ifelse(info_user$verified, "Verificados", "Sin verificar")
# info_user$verificado <- as.factor(info_user$verificado)

Todo: * Juntar usuarios finales, usuarios que fueron replicados * Que hace que un usuario sea más divulgado? Hay alguna medida de relevancia de un usuario? Aquellos más populares (Segun que criterio?) son de que tipo? Instituciones, usuarios comunes, bots? Que tan activos son? Influye eso? Desde que dispositivo lo hacen? Que tipo de texto crean? Que hashtags usan? De que regiones son? Hay algo interesante ahí? Hay predominio de algun pais? Hay paises donde se usa más el twitter?

Tipos de usuarios:


user_tweets_estadisticas <- mongo(db="DMUBA", collection="user_tweets_estadisticas")
# User base
info_user <- user_tweets_estadisticas$find()
summary(info_user$is_none)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.000   1.000   1.137   1.000  31.000 
info_user[info_user == 0] <- 0.00001
data_log_1 <- as.data.frame(apply(info_user[,3:7], 2, log))
# Plot de grupos

plot(sort(data_log_1$is_rt))

plot(sort(data_log_1$is_only_rt))

plot(sort(data_log_1$is_only_qt))

plot(sort(data_log_1$is_none))

plot(sort(data_log_1$is_qt))

TODO: Binning con esto? Alinear distintos grupos en cada categoria? Solo clasificarlos?

Usuarios con más tweets

head(info_user[order(info_user$count, decreasing = T),])

Curiosamente, los usuarios finales con más tweets son creadores. serán bots?

Categorizar

info_user$tipo <- ifelse(info_user$is_none > info_user$is_only_rt + info_user$is_only_rt, "Creador", "Difusor")
barplot(table(info_user$tipo))
info_user_graf <- data.frame(table(info_user$tipo))
names(info_user_graf) <- c("Tipo_usuario", "Cantidad")

png(filename="tipo_usuario_creacion.png", width=1000, bg="white")
ggplot(info_user_graf, aes(x=reorder(Tipo_usuario , Cantidad), y=Cantidad, fill=Tipo_usuario)) + 
    geom_bar(stat="identity") +
    scale_fill_brewer(palette="Set2") +
    labs(
      title = "",
      subtitle = "",
      caption = "",
      tag = ""
      ) +
    xlab("") +
    ylab("") +
    theme(plot.title = element_text(hjust = 0.5), 
          axis.text=element_text(size=14),
          axis.text.y = element_text( margin = margin(10, 10, 10, 10)),
          axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),
              legend.text=element_text(size=14),
    # theme(plot.title = element_text(hjust = 0.5), 
    #       axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10))
          ) +
    coord_flip()
dev.off()
png 
  2 

Usuarios según popularidad

user_estadisticas <- mongo(db="DMUBA", collection="user_estadisticas")
info_user <- user_estadisticas$find()

data_log <- as.data.frame(apply(info_user[,5:9], 2, log10))
info_user[info_user == 0] <- 0.00001
info_user[is.na(info_user)] <- 0.0001
data_log_1 <- as.data.frame(apply(info_user[,5:9], 2, log10))

Correllations

ggpairs(data_log_1)

There were 25 warnings (use warnings() to see them)
bin_eq_freq <- discretize(data_log_1$followers_count,"equalfreq", 20)
bin_eq_freq$followers_count = data_log_1$followers_count

# Por cada bin calculamos la media y reemplazamos en el atributo suavizado
for(bin in 1:20){
  bin_eq_freq$suavizado[ bin_eq_freq$X==bin] = mean(bin_eq_freq$followers_count[ bin_eq_freq$X==bin])
}

# grafico Sepal.Width ordenado de menor a mayor
plot(sort(data_log_1$followers_count) , type = "p", col="red", 
     ylab = "followers_count", xlab = "Observaciones", main = "Dato original vs suavizado")
# Agrego la serie de la variable media 
lines(sort(bin_eq_freq$suavizado),
      type = "p", col="blue")
legend("topleft", legend=c("Original", "Suavizado"), col=c("red", "blue"), lty=1)



bin_eq_freq <- discretize(data_log_1$listed_count,"equalfreq", 20)
bin_eq_freq$listed_count = data_log_1$listed_count

# Por cada bin calculamos la media y reemplazamos en el atributo suavizado
for(bin in 1:20){
  bin_eq_freq$suavizado[ bin_eq_freq$X==bin] = mean(bin_eq_freq$listed_count[ bin_eq_freq$X==bin])
}

# grafico Sepal.Width ordenado de menor a mayor
plot(sort(data_log_1$listed_count) , type = "p", col="red", 
     ylab = "listed_count", xlab = "Observaciones", main = "Dato original vs suavizado")
# Agrego la serie de la variable media 
lines(sort(bin_eq_freq$suavizado),
      type = "p", col="blue")
legend("topleft", legend=c("Original", "Suavizado"), col=c("red", "blue"), lty=1)

Usuarios según actividad

# no_na_data <- data_log_1[!is.na(data_log_1$statuses_count),]
bin_eq_freq <- discretize(data_log_1$statuses_count,"equalwidth", 5)
bin_eq_freq$statuses_count = data_log_1$statuses_count

# Por cada bin calculamos la media y reemplazamos en el atributo suavizado
for(bin in 1:5){
  bin_eq_freq$suavizado[ bin_eq_freq$X==bin] = mean(bin_eq_freq$statuses_count[ bin_eq_freq$X==bin])
}

# grafico Sepal.Width ordenado de menor a mayor
plot(sort(data_log_1$statuses_count) , type = "p", col="red", 
     ylab = "statuses_count", xlab = "Observaciones", main = "Dato original vs suavizado")
# Agrego la serie de la variable media 
lines(sort(bin_eq_freq$suavizado),
      type = "p", col="blue")
legend("topleft", legend=c("Original", "Suavizado"), col=c("red", "blue"), lty=1)


# no_na_data <- data_log_1[!is.na(data_log_1$favourites_count),]
bin_eq_freq <- discretize(data_log_1$favourites_count,"equalwidth", 10)
bin_eq_freq$favourites_count = data_log_1$favourites_count

# Por cada bin calculamos la media y reemplazamos en el atributo suavizado
for(bin in 1:10){
  bin_eq_freq$suavizado[ bin_eq_freq$X==bin] = mean(bin_eq_freq$favourites_count[ bin_eq_freq$X==bin])
}

# grafico Sepal.Width ordenado de menor a mayor
plot(sort(data_log_1$favourites_count) , type = "p", col="red", 
     ylab = "favourites_count", xlab = "Observaciones", main = "Dato original vs suavizado")
# Agrego la serie de la variable media 
lines(sort(bin_eq_freq$suavizado),
      type = "p", col="blue")
legend("topleft", legend=c("Original", "Suavizado"), col=c("red", "blue"), lty=1)

TODO: * Dentro de los creadores, alguno fue retweteado? Citado? Cual es el impacto de los creadores? * Dentro de los difusores, que impacto tienen? Que relevancia tienen los creadores originales? Cuando tweets fueron amplificados más de una vez en el grupo de twitteros finales? * Es muy simplista esto? Funciona? Hay dispositivos privilegiados? Usan software para publicaciones los creadores? Los difusores? * Entre los creadores, hay verificados? Hay alguna forma de evaluar la confiabilidad o la veracidad de lo que dicen? * Entre los difusores, hay fake news? Hay difusion indiscriminada? Hay relacion entre algun par de usuarios? Hay alguna persona que tiene más difusion que otra? s

Paises

There were 22 warnings (use warnings() to see them)
# png(filename="location_porc_na.png", width=1000, bg="white")
ggplot(df, aes(x=reorder(Atributo, porcentaje_na), y=porcentaje_na, fill=Atributo)) + 
  geom_bar(stat="identity") +
  scale_fill_brewer(palette="Set2") +
  labs(
    title = "",
    subtitle = "",
    caption = "",
    tag = ""
  ) +
  xlab("") +
  ylab("") +
  theme(plot.title = element_text(hjust = 0.5), 
        axis.text=element_text(size=14),
        axis.text.y = element_text( margin = margin(10, 10, 10, 10)),
        axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),
        legend.text=element_text(size=14),
        aspect.ratio = 1/1
        ) +
  coord_flip()
# dev.off()

#Unimos continente

Clasificar en noticias - politica - otros


t <- mongo(collection = "tweets_lower", db = "DMUBA")
aux <- t$aggregate('[{"$project":{"_id": "$_id","user_id":"$user_id","screen_name":"$screen_name","text":"$description"}}]')
aux$text <- tolower(aux$text)
aux$text <- gsub("http.*","",aux$text)
aux$text <- gsub("https.*","",aux$text)

# #Quitando los hashtags y usuarios en los tweets_text
# aux$text <- gsub("#\\w+","",aux$text)
aux$text <- gsub("@\\w+","",aux$text)

aux$text <- gsub("[[:punct:]]","",aux$text)
aux$text <- gsub("\\w*[0-9]+\\w*\\s*", "",aux$text)

aux$text <- gsub("[[:punct:]]","",aux$text)
aux$text <- gsub("[^[:alnum:][:blank:]?&/\\-]", "", aux$text)
aux$text <- iconv(aux$text,from="UTF-8",to="ASCII//TRANSLIT")
  
palabras_noticias <- c("noticia", "periodismo", "periodista", 'periodico', "news", 'journalist', "reportero", "programa de tv", 'television', 'Reuters ', 'elpaisamerica', 'productora', 'conductor', 'columnista', 'corresponsal', 'telesur')
aux$is_news_related <- F
for (i in palabras_noticias) {
  aux$is_news_related <- ifelse(grepl(i, aux$text, fixed= T), T, aux$is_news_related)
}
palabras_politica <- c("politico", "senador", "diputado", "alcalde", "subsecretario", "secretario", "secretaria", "presidencia", "presidente", "ministerio", "ministro", "ministra", "público", "publico", "canciller", "Partido Socialista", "PSUV", "partido del pueblo", 'asamblea nacional')
aux$is_politic_related <- F
for (i in palabras_politica) {
  aux$is_politic_related <- ifelse(grepl(i, aux$text, fixed= T), T, aux$is_politic_related)
}
aux$tipo_user = "Normal"
aux[aux$is_news_related,]$tipo_user <- "Medio"
aux[aux$is_politic_related,]$tipo_user <- "Politica"
aux$is_news_related <- NULL
aux$is_politic_related <- NULL
aux$text <- NULL

aux[aux$tipo_user=='Politica',]
# tweets <- merge(tweets, aux, by="tweet_id")
aux %>% group_by(screen_name) %>% summarise(tipo = max(tipo_user))
# table(aux$tipo_user)
aux <- t$aggregate('[{"$project":{"_id":"$_id","user_id":"$retweet_user_id","screen_name":"$retweet_screen_name","text":"$retweet_description"}}]')
aux <- aux[!is.na(aux$screen_name),]
aux$text <- tolower(aux$text)
aux$text <- gsub("http.*","",aux$text)
aux$text <- gsub("https.*","",aux$text)

# #Quitando los hashtags y usuarios en los tweets_text
# aux$text <- gsub("#\\w+","",aux$text)
aux$text <- gsub("@\\w+","",aux$text)

aux$text <- gsub("[[:punct:]]","",aux$text)
aux$text <- gsub("\\w*[0-9]+\\w*\\s*", "",aux$text)

aux$text <- gsub("[[:punct:]]","",aux$text)
aux$text <- gsub("[^[:alnum:][:blank:]?&/\\-]", "", aux$text)
aux$text <- iconv(aux$text,from="UTF-8",to="ASCII//TRANSLIT")
  
palabras_noticias <- c("noticia", "periodismo", "periodista", 'periodico', "news", 'journalist', "reportero", "programa de tv", 'television', 'Reuters ', 'elpaisamerica', 'productora', 'conductor', 'columnista', 'corresponsal', 'telesur')
aux$is_news_related <- F
for (i in palabras_noticias) {
  aux$is_news_related <- ifelse(grepl(i, aux$text, fixed= T), T, aux$is_news_related)
}
palabras_politica <- c("politico", "senador", "diputado", "alcalde", "subsecretario", "secretario", "secretaria", "presidencia", "presidente", "ministerio", "ministro", "ministra", "público", "publico", "canciller", "Partido Socialista", "PSUV", "partido del pueblo", 'asamblea nacional')
aux$is_politic_related <- F
for (i in palabras_politica) {
  aux$is_politic_related <- ifelse(grepl(i, aux$text, fixed= T), T, aux$is_politic_related)
}
# barplot(tweets$is_news_related)
# barplot(tweets$is_politic_related)
aux$tipo_user = "Normal"
aux[aux$is_news_related,]$tipo_user <- "Medio"
aux[aux$is_politic_related,]$tipo_user <- "Politica"
aux$is_news_related <- NULL
aux$is_politic_related <- NULL
aux$text <- NULL

aux[aux$tipo_user=='Politica',]
# tweets <- merge(tweets, aux, by="tweet_id")
aux %>% group_by(screen_name) %>% summarise(tipo = max(tipo_user))
# table(aux$tipo_user)
names(user)
[1] "_id"                 "user_id"             "retweet_screen_name" "tipo_user"          
names(aux)
[1] "_id"         "user_id"     "screen_name" "tipo_user"  
LS0tDQp0aXRsZTogIlRwIDEgLSBUd2VldHMgc29icmUgY292aWQtMTkiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiMgU29sdWNpw7NuIFRwIDAxDQoNClRwIDEgLSBUd2VldHMgc29icmUgY292aWQtMTkuIA0KQnVzY2FuZG8gcGF0cm9uZXMgaW50ZXJlc2FudGVzLg0KDQojIyBMaWJyZXLDrWFzDQoNCmBgYHtyfQ0KbGlicmFyeSgiZ2dwbG90MiIpDQpsaWJyYXJ5KCJyZWFkciIpDQpsaWJyYXJ5KCJkcGx5ciIpDQpsaWJyYXJ5KCJoaWdoY2hhcnRlciIpDQpsaWJyYXJ5KCJ0cmVlbWFwIikNCmxpYnJhcnkoIm1vZGVlc3QiKQ0KbGlicmFyeSgiR0dhbGx5IikNCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJocmJydGhlbWVzIikNCmxpYnJhcnkoInRpZHlyIikNCmxpYnJhcnkoIlZJTSIpDQpsaWJyYXJ5KCJlMTA3MSIpDQpsaWJyYXJ5KCJtaWNlIikNCmxpYnJhcnkoIm1vbmdvbGl0ZSIpDQoNCmxpYnJhcnkoIlNub3diYWxsQyIpDQpsaWJyYXJ5KCJ0bSIpDQpsaWJyYXJ5KCJ0d2l0dGVSIikNCmxpYnJhcnkoInN5dXpoZXQiKQ0KDQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQ0KbGlicmFyeSgibHVicmlkYXRlIikNCg0KbGlicmFyeSgiUkNvbG9yQnJld2VyIikNCmxpYnJhcnkoImluZm90aGVvIik7ICMgRGlzY3JldGl6ZSB2YXJpYWJsZQ0KDQpgYGANCg0KIyMgUmVmZXJlbmNpYSB0d2VldHMNCmBgYHtyfQ0KdHdlZXRzIDwtIG1vbmdvKGNvbGxlY3Rpb24gPSAidHdlZXRzX21vbmdvX2NvdmlkMTkiLCBkYiA9ICJETVVCQSIpDQpgYGANCg0KIyMgTm9tYnJlcyBkZSBjb2x1bW5hcw0KYGBge3J9DQpuYW1lcyh0d2VldHMkZmluZCgpKQ0KYGBgDQoNCiMgVGlwb3MgZGUgdHdlZXRzDQpgYGB7cn0NCnQgPC0gbW9uZ28oZGI9IkRNVUJBIiwgY29sbGVjdGlvbj0idHdlZXRfdHlwZSIpDQp0d2VldHNfdHlwZXMgPC0gdCRmaW5kKCkNCmBgYA0KDQpgYGB7cn0NCmNhdCgiQ2FudGlkYWRlcyBkZSB0d2VldHMgcG9yIHRpcG8gXG5cbiIpDQpjYXQoIlx0KiBUd2VldHM6ICIsIG5yb3codHdlZXRzX3R5cGVzKSwgIlxuIikNCmNhdCgiXHQqIFNvbG8gUlQ6ICIsIG5yb3codHdlZXRzX3R5cGVzW3R3ZWV0c190eXBlcyRpc19yZXR3ZWV0ICYgIXR3ZWV0c190eXBlcyRpc19xdW90ZSxdKSwgIlxuIikNCmNhdCgiXHQqIFNvbG8gUVQ6ICIsIG5yb3codHdlZXRzX3R5cGVzWyF0d2VldHNfdHlwZXMkaXNfcmV0d2VldCAmIHR3ZWV0c190eXBlcyRpc19xdW90ZSxdKSwgIlxuIikNCmNhdCgiXHQqIFJUIHkgUVQ6ICIsIG5yb3codHdlZXRzX3R5cGVzW3R3ZWV0c190eXBlcyRpc19yZXR3ZWV0ICYgdHdlZXRzX3R5cGVzJGlzX3F1b3RlLF0pLCAiXG4iKQ0KY2F0KCJcdCogVFcgb3JpZ2luYWxlczogIiwgbnJvdyh0d2VldHNfdHlwZXNbIXR3ZWV0c190eXBlcyRpc19yZXR3ZWV0ICYgIXR3ZWV0c190eXBlcyRpc19xdW90ZSxdKSwgIlxuIikNCg0KYGBgDQoNCmBgYHtyfQ0KdHdlZXRzX3R5cGVzJHRpcG8gPC0gIiINCnR3ZWV0c190eXBlc1t0d2VldHNfdHlwZXMkaXNfcmV0d2VldCAmICF0d2VldHNfdHlwZXMkaXNfcXVvdGUsXSR0aXBvIDwtICJTb2xvIFJUIg0KdHdlZXRzX3R5cGVzWyF0d2VldHNfdHlwZXMkaXNfcmV0d2VldCAmIHR3ZWV0c190eXBlcyRpc19xdW90ZSxdJHRpcG8gPC0gIlNvbG8gUVQiDQp0d2VldHNfdHlwZXNbdHdlZXRzX3R5cGVzJGlzX3JldHdlZXQgJiB0d2VldHNfdHlwZXMkaXNfcXVvdGUsXSR0aXBvIDwtICJSUSB5IFJUIg0KdHdlZXRzX3R5cGVzWyF0d2VldHNfdHlwZXMkaXNfcmV0d2VldCAmICF0d2VldHNfdHlwZXMkaXNfcXVvdGUsXSR0aXBvIDwtICJPcmlnaW5hbCINCmBgYA0KDQoNCmBgYHtyfQ0KIyBuYW1lcyA9IGMoJ1NvbG8gUlQnLCAnU29sbyBRVCcsICdSVCArIFFUJywgJ09yaWdpbmFsJykNCiMgY2FudGlkYWRlcyA9IGMobnJvdyh0d2VldHNfdHlwZXNbdHdlZXRzX3R5cGVzJGlzX3JldHdlZXQgJiAhdHdlZXRzX3R5cGVzJGlzX3F1b3RlLF0pLA0KIyAgICAgICAgICAgICAgICBucm93KHR3ZWV0c190eXBlc1shdHdlZXRzX3R5cGVzJGlzX3JldHdlZXQgJiB0d2VldHNfdHlwZXMkaXNfcXVvdGUsXSksDQojICAgICAgICAgICAgICAgIG5yb3codHdlZXRzX3R5cGVzW3R3ZWV0c190eXBlcyRpc19yZXR3ZWV0ICYgdHdlZXRzX3R5cGVzJGlzX3F1b3RlLF0pLA0KIyAgICAgICAgICAgICAgICBucm93KHR3ZWV0c190eXBlc1shdHdlZXRzX3R5cGVzJGlzX3JldHdlZXQgJiAhdHdlZXRzX3R5cGVzJGlzX3F1b3RlLF0pDQojICAgICAgICAgICAgICAgKQ0KIyAgICAgICAgICAgICAgICANCmdyYWZpY29fdGlwb3MgPC0gZGF0YS5mcmFtZSh0YWJsZSh0d2VldHNfdHlwZXMkdGlwbykpDQoNCiMgYmFycGxvdChzb3J0KGdyYWZpY29fdGlwb3MkRnJlcSwgZGVjcmVhc2luZz1UUlVFKSwgbGVnZW5kLnRleHQ9Z3JhZmljb190aXBvcyRWYXIxLCBjb2w9YygncmVkJywnZ3JlZW4nLCdibHVlJywnYnJvd24nKSkNCiMgYmFycGxvdChoZWlnaHQ9c29ydChncmFmaWNvX3RpcG9zJEZyZXEsIGRlY3JlYXNpbmc9VFJVRSksIG5hbWVzPWdyYWZpY29fdGlwb3MkVmFyMSwgY29sPXJnYigwLjIsMC40LDAuNiwwLjYpICkNCg0KbmFtZXMoZ3JhZmljb190aXBvcykgPC0gYygiVGlwb3MiLCAiQ2FudGlkYWQiKQ0KDQpjb3VsIDwtIGJyZXdlci5wYWwoNSwgIlNldDIiKSANCmJhcnBsb3QoaGVpZ2h0PXNvcnQoZ3JhZmljb190aXBvcyRDYW50aWRhZCwgZGVjcmVhc2luZz1UUlVFKSwgbmFtZXM9Z3JhZmljb190aXBvcyRUaXBvcywgY29sPWNvdWwgKQ0KDQpgYGANCmBgYHtyfQ0KDQojIGNvdWwgPC0gYnJld2VyLnBhbCg1LCAiU2V0MiIpIA0KDQojIHBuZyhmaWxlbmFtZT0idGlwb190d2VldC5wbmciLCB3aWR0aD0xMDAwLCBiZz0id2hpdGUiKQ0KZ2dwbG90KGdyYWZpY29fdGlwb3MsIGFlcyh4PXJlb3JkZXIoVGlwb3MsIENhbnRpZGFkKSwgeT1DYW50aWRhZCwgZmlsbD1UaXBvcykpICsgDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iU2V0MiIpICsNCiAgICBsYWJzKA0KICAgICAgdGl0bGUgPSAiIiwNCiAgICAgIHN1YnRpdGxlID0gIiIsDQogICAgICBjYXB0aW9uID0gIiIsDQogICAgICB0YWcgPSAiIg0KICAgICAgKSArDQogICAgeGxhYigiIikgKw0KICAgIHlsYWIoIiIpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgDQogICAgICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEyKSwNCiAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggbWFyZ2luID0gbWFyZ2luKDEwLCAxMCwgMTAsIDEwKSksDQogICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMTAsIHIgPSAxMCwgYiA9IDEwLCBsID0gMTApKSwNCiAgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgICBjb29yZF9mbGlwKCkNCiMgZGV2Lm9mZigpDQpgYGANCg0KIyMjICUgZGUgVmVyaWZpY2Fkb3Mgc2Vnw7puIHRpcG8gZGUgdHdlZXQNCmBgYHtyfQ0KDQp0d2VldHMgPC0gbW9uZ28oZGI9IkRNVUJBIiwgY29sbGVjdGlvbj0idHdlZXRfY29tcGxldG9fZXN0YWRpc3RpY2FzIikNCm51bWVyaWNvcyA8LSB0d2VldHMkZmluZCgpDQoNCiMgVGlwb3MNCm51bWVyaWNvcyRUaXBvIDwtICIiDQpudW1lcmljb3NbbnVtZXJpY29zJGlzX3JldHdlZXQgJiAhbnVtZXJpY29zJGlzX3F1b3RlLF0kVGlwbyA8LSAiU29sbyBSVCINCm51bWVyaWNvc1shbnVtZXJpY29zJGlzX3JldHdlZXQgJiBudW1lcmljb3MkaXNfcXVvdGUsXSRUaXBvIDwtICJTb2xvIFFUIg0KbnVtZXJpY29zW251bWVyaWNvcyRpc19yZXR3ZWV0ICYgbnVtZXJpY29zJGlzX3F1b3RlLF0kVGlwbyA8LSAiUVQgeSBSVCINCm51bWVyaWNvc1shbnVtZXJpY29zJGlzX3JldHdlZXQgJiAhbnVtZXJpY29zJGlzX3F1b3RlLF0kVGlwbyA8LSAiT3JpZ2luYWwiDQoNCm51bWVyaWNvcyR2ZXJpZmljYWRvIDwtIEYNCm51bWVyaWNvc1tudW1lcmljb3MkVGlwbyA9PSAiU29sbyBRVCIsXSR2ZXJpZmljYWRvIDwtICBudW1lcmljb3NbbnVtZXJpY29zJFRpcG8gPT0gIlNvbG8gUVQiLF0kcXVvdGVkX3ZlcmlmaWVkDQpudW1lcmljb3NbbnVtZXJpY29zJFRpcG8gPT0gIk9yaWdpbmFsIixdJHZlcmlmaWNhZG8gPC0gIG51bWVyaWNvc1tudW1lcmljb3MkVGlwbyA9PSAiT3JpZ2luYWwiLF0kdmVyaWZpZWQNCm51bWVyaWNvc1tudW1lcmljb3MkVGlwbyA9PSAiU29sbyBSVCIsXSR2ZXJpZmljYWRvIDwtICBudW1lcmljb3NbbnVtZXJpY29zJFRpcG8gPT0gIlNvbG8gUlQiLF0kcmV0d2VldF92ZXJpZmllZA0KbnVtZXJpY29zW251bWVyaWNvcyRUaXBvID09ICJRVCB5IFJUIixdJHZlcmlmaWNhZG8gPC0gIG51bWVyaWNvc1tudW1lcmljb3MkVGlwbyA9PSAiUVQgeSBSVCIsXSRyZXR3ZWV0X3ZlcmlmaWVkDQoNCm51bWVyaWNvcyR2ZXJpZmljYWRvX2dyYWZpY28gPC0gIiINCm51bWVyaWNvc1tudW1lcmljb3MkdmVyaWZpY2FkbyxdJHZlcmlmaWNhZG9fZ3JhZmljbyA8LSAiU2kiDQpudW1lcmljb3NbIW51bWVyaWNvcyR2ZXJpZmljYWRvLF0kdmVyaWZpY2Fkb19ncmFmaWNvIDwtICJObyINCg0KYGBgDQoNCmBgYHtyfQ0KDQojIHBuZyhmaWxlbmFtZT0idGlwb194X3R3ZWV0X2dyaWQyLnBuZyIsIHdpZHRoPTEwMDAsIGJnPSJ3aGl0ZSIpDQpnZ3Bsb3QoZGF0YT1udW1lcmljb3MsIGFlcyh4PXZlcmlmaWNhZG9fZ3JhZmljbywgZmlsbD1UaXBvKSkgKyANCiAgICAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iU2V0MiIpICsNCiAgICAgICAgZ2VvbV9iYXIoKSArDQogICAgICAgIGxhYnMoDQogICAgICAgICAgdGl0bGUgPSAiIiwNCiAgICAgICAgICBzdWJ0aXRsZSA9ICIiLA0KICAgICAgICAgIGNhcHRpb24gPSAiIiwNCiAgICAgICAgICB0YWcgPSAiIg0KICAgICAgICAgICkgKw0KICAgICAgICB4bGFiKCIiKSArDQogICAgICAgIHlsYWIoIiIpICsNCiAgICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIA0KICAgICAgICAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLA0KICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggbWFyZ2luID0gbWFyZ2luKDEwLCAxMCwgMTAsIDEwKSksDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDEwLCByID0gMTAsIGIgPSAxMCwgbCA9IDEwKSksDQogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEwKSwNCiAgICAgICAgICAgICAgYXNwZWN0LnJhdGlvPTE5LzE5KSArDQogICAgICAgIGZhY2V0X3dyYXAofiBUaXBvLCBucm93PTIpDQojIGRldi5vZmYoKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YT10d2VldHNfdHlwZXMsIGFlcyh4PXZlcmlmaWVkLCBmaWxsPXRpcG8pKSArIA0KICBnZW9tX2JhcigpICsgZmFjZXRfd3JhcCh+IHRpcG8sIG5yb3c9MikNCmBgYA0KDQpIYXkgbcOhcyB1c3VhcmlvcyB2ZXJpZmljYWRvcyBlbiBlbCBjb250ZW5pZG8gbnVldm8uIEEgc3UgdmV6LCBoYXkgbcOhcyB2ZXJpZmljb3MgZW4gZWwgY29udGVuaWRvIGNpdGFkby4gRXNvIGhhYmxhIGRlIHF1ZSB1biB1c3VhcmlvIHZlcmlmaWNhZG8gY3JlYSB1biBjb250ZW5pZG8gZGUgbWF5b3IgY2FsaWRhZCAoTcOhcyBkaWZ1bmRpZG8geSBub3ZlZG9zbykuDQoNCk1pZW50cmFzIHF1ZSBlbCB1c3VhcmlvIGRpZnVzb3IgeSBsb3MgcmV0d2VldHMsIHNpIGJpZW4gYXVtZW50YW4gZWwgYWxjYW5jZSBkZSBsb3MgdHdlZXRzLCBubyB0aWVuZW4gdW5hIGNhbGlkYWQgYWx0YS4gDQoNCiMjIFR3ZWV0cyBzZWfDum4gdGllbXBvDQoNCmBgYHtyfQ0KdCA8LSBtb25nbyhkYj0iRE1VQkEiLCBjb2xsZWN0aW9uPSJmZWNoYXMiKQ0KdHdlZXRzX2ZlY2hhcyA8LSB0JGZpbmQoKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeSh0d2VldHNfZmVjaGEpDQpgYGANCg0KDQpFbiB1biBwcmltZXIgaW50ZW50byBkZSBncmFmaWNhciwgdmVtb3MgcXVlIGxvcyBkYXRvcyBlc3RhbiBkaXN0cmlidWlkb3MgZGUgdW5hIGZvcm1hIHBhcnRpY3VsYXIuIExhIHByaW1lcmEgcHJlZ3VudGEgZXMgwr9IYXkgYWxndW5hIGZlY2hhIHF1ZSBwcmVzZW50w7MgdW5hIGNhbnRpZGFkIGFuw7NtYWxhIGRlIGRhdG9zPw0KDQpFbCAyIGRlIG1heW8gbG8gZXMuIFNpbiBlbWJhcmdvLCBubyBmdWUgdW4gZMOtYSBlbiBlbCBxdWUgYWNvbnRlY2nDsyBhbGd1bmEgY29zYS4gTmkgZXMgZmVyaWFkbyAoMS81KSwgbmkgZnVlIGTDrWEgZGUgYW51bmNpb3MgKDI1LzQpLg0KDQpgYGB7cn0NCiMgcGxvdCh0d2VldHNfZmVjaGEkZmVjaGEpDQojIGJhcnBsb3QodGFibGUoYXMuRGF0ZSh0d2VldHNfZmVjaGEkZmVjaGEpKSkNCmY8LSBkYXRhLmZyYW1lKHRhYmxlKGFzLkRhdGUodHdlZXRzX2ZlY2hhJGZlY2hhKSkpDQpnZ3Bsb3QoZGF0YT1mLCBhZXMoeD1GcmVxKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0iIzY5YjNhMiIsIGNvbG9yPSIjZTllY2VmIiwgYWxwaGE9MC45KSArDQogICAgZ2d0aXRsZSgiQmluIHNpemUgPSAzIikgKw0KICAgIHRoZW1lX2lwc3VtKCkgKw0KICAgIHRoZW1lKA0KICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KQ0KICAgICkNCmBgYA0KDQpBZ3J1cGFuZG8gZW4gZnJhY2Npb25lcyBtZW5vcywgNSBtaW51dG9zLCB2ZW1vcyBxdWUgbG8gcXVlIGFjb250ZWNpw7MgZnVlIHVuYSB2ZW50YW5hIGRlIGNhcHR1cmEgZGUgZGF0b3MgZGVzaWd1YWwuIEFsIHJlZHVjaXIgbGEgdmVudGFuYSBkZSB0aWVtcG8sIHZlbW9zIHF1ZSBoYXkgdW5hIGRpc3RyaWJ1Y2nDs24gbcOhcyB1bmlmb3JtZS4gSWd1YWxtZW50ZSBzaWd1ZSBwbGFudGVhbmRvc2UgbGEgcHJlZ3VudGEsIHBvZHLDrWFtb3MgYW5hbGl6YXJsbyBkZSBhIG1pbnV0b3MsIG8gY29uIGRpZmVyZW5jaWFzIHBvcmNlbnR1YWxlcywgcGFyYSB2ZXIgc2kgcmVhbG1lbnRlIGh5YSBhbGdvIGFow60uDQoNCmBgYHtyfQ0KdHdlZXRzX2ZlY2hhJHQgPC0geW1kX2htcyh0d2VldHNfZmVjaGEkZmVjaGEpDQp0d2VldHNfZmVjaGEkdGMgPC0gY3V0KHR3ZWV0c19mZWNoYSR0LCBicmVha3MgPSAiNSBtaW4iKSAgDQpjYW50XzVfbWluIDwtIGNvdW50KHR3ZWV0c19mZWNoYSwgdGMpDQpiYXJwbG90KGNhbnRfNV9taW4kbiwgbGVnZW5kLnRleHQ9Y2FudF81X21pbiR0YykNCiMjIFR3ZWV0cyBwb3IgZmVjaGENCnR3ZWV0c19mZWNoYSR0IDwtIHltZF9obXModHdlZXRzX2ZlY2hhJGZlY2hhKQ0KDQojIFBvciBtaW51dG8gZXN0w6EgbcOhcyBlcXVpbGlicmFkbykNCnR3ZWV0c19mZWNoYSR0YyA8LSBjdXQodHdlZXRzX2ZlY2hhJHQsIGJyZWFrcyA9ICIxIG1pbiIpICANCmNhbnRfNV9taW4gPC0gY291bnQodHdlZXRzX2ZlY2hhLCB0YykNCmJhcnBsb3QoY2FudF81X21pbiRuKQ0KYGBgDQpMYSB2YXJpYWJsZSB0ZW1wb3JhbCBwYXJlY2Ugc2VyIGFyYml0cmFyaWEuIA0KDQpBbGdvIGEgc2VndWlyIGludmVzdGlnYW5kbyBlcyBsYSB2ZW50YW5hIHRlbXBvcmFsIGVudHJlOg0KICAqIEZlY2hhIGNyZWFkYSB5IGZlY2hhIGRlIGNyZWFjaW9uIGRlbCByZXR3ZWV0DQogICogRmVjaGEgY3JlYWRhIHkgZmVjaGEgZGUgY3JlYWNpb24gZGVsIHF1b3RlZA0KICANCiAgDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KCJwbG90bHkiKQ0KbGlicmFyeShocmJydGhlbWVzKQ0KIyB0d2VldHNfZmVjaGEkZmVjaGENCnR3ZWV0c19mZWNoYSRmZWNoYV9zdHIgPC0gIGxhcHBseSh0d2VldHNfZmVjaGEkdGMsIGFzLmNoYXJhY3RlcikNCmIgPC0gYXMuUE9TSVhsdChzdHJwdGltZSh0d2VldHNfZmVjaGEkdGMsIGZvcm1hdCA9ICIlSDolTTolUyIpKQ0KY2FudF81X21pbiRmZWNoYSA8LSBhcy5EYXRlKGNhbnRfNV9taW4kdGMpDQpjYW50XzVfbWluJGhvcmEgPC0gIGZvcm1hdChzdHJwdGltZShjYW50XzVfbWluJHRjLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKSwgZm9ybWF0PSIlSDolTTolUyIpDQoNCnAgPC0gY2FudF81X21pbiAlPiUNCiAgZ2dwbG90KCBhZXMoeD1yZW9yZGVyKGhvcmEsIGhvcmEpLCB5PW4sIGZpbGw9bikpICsgDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogICAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSdyZWQnLCBtaWQ9J3Nub3czJywgaGlnaD0nZGFya2dyZWVuJywgc3BhY2U9J0xhYicpICsNCiAgICAgICAgbGFicygNCiAgICAgICAgICB0aXRsZSA9ICIiLA0KICAgICAgICAgIHN1YnRpdGxlID0gIiIsDQogICAgICAgICAgY2FwdGlvbiA9ICIiLA0KICAgICAgICAgIHRhZyA9ICIiDQogICAgICAgICAgKSArDQogICAgICAgIHhsYWIoIiIpICsNCiAgICAgICAgeWxhYigiIikgKw0KICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKSArDQogICAgZmFjZXRfd3JhcCh+IGZlY2hhLCBucm93PTQpDQoNCnBuZyhmaWxlbmFtZT0idGlwb194X3R3ZWV0LnBuZyIsIHdpZHRoPTEwMDAsIGJnPSJ3aGl0ZSIpDQpwDQpkZXYub2ZmKCkNCg0KIyBUdXJuIGl0IGludGVyYWN0aXZlIHdpdGggZ2dwbG90bHkNCnAgPC0gZ2dwbG90bHkocCkNCnANCmBgYA0KDQoNCiMjIFRleHRvDQoNCmBgYHtyfQ0KdHdlZXRzX3RleHQgPC0gdHdlZXRzJGFnZ3JlZ2F0ZSgnW3sNCiAgICAgICAgICAgICIkcHJvamVjdCI6IHsgDQogICAgICAgICAgICAgICAgIl9pZCI6ICIkX2lkIiwNCiAgICAgICAgICAgICAgICAidGV4dCI6ICIkdGV4dCINCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIF0nKQ0KIyBzdW1tYXJ5KHR3ZWV0c190ZXh0KQ0KIyAjIHR3ZWV0c190ZXh0JGNhbnRDaGFycyA8LSBuY2hhcih0d2VldHNfdGV4dCR0ZXh0KQ0KIyBzdW1tYXJ5KHR3ZWV0c190ZXh0KQ0KIyBQb3IgaGF5IHVuIHR3ZWV0IGRlIDkwMCBjaGFyPyBzZXLDoSBwb3IgdXJsIG8gY29zYXMgYXPDrT8NCmJveHBsb3QodHdlZXRzX3RleHQkY2FudENoYXJzKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHR3ZWV0c190ZXh0LCBhZXMoeD1jYW50Q2hhcnMpKSArDQogIGdlb21fZGVuc2l0eShmaWxsPSIjNjliM2EyIiwgY29sb3I9IiNlOWVjZWYiLCBhbHBoYT0wLjgpICsNCiAgZ2d0aXRsZSgiQ2FudGlkYWQgZGUgY2F0YWN0ZXJlcyBwb3IgdHdlZXQiKSArDQogIHRoZW1lX2lwc3VtKCkNCmBgYA0KIyMjIE1lbm9zIHVzZXIgeSBsaW5rcyByZWZlcmVuY2VzDQoNCmBgYHtyfQ0KdHdlZXRzX3RleHQuZGYyIDwtIHR3ZWV0c190ZXh0DQp0d2VldHNfdGV4dC5kZjIkdGV4dCA8LSBnc3ViKCJodHRwLioiLCIiLHR3ZWV0c190ZXh0LmRmMiR0ZXh0KQ0KdHdlZXRzX3RleHQuZGYyJHRleHQgPC0gZ3N1YigiaHR0cHMuKiIsIiIsdHdlZXRzX3RleHQuZGYyJHRleHQpDQoNCiNRdWl0YW5kbyBsb3MgaGFzaHRhZ3MgeSB1c3VhcmlvcyBlbiBsb3MgdHdlZXRzX3RleHQNCnR3ZWV0c190ZXh0LmRmMiR0ZXh0IDwtIGdzdWIoIiNcXHcrIiwiIix0d2VldHNfdGV4dC5kZjIkdGV4dCkNCnR3ZWV0c190ZXh0LmRmMiR0ZXh0IDwtIGdzdWIoIkBcXHcrIiwiIix0d2VldHNfdGV4dC5kZjIkdGV4dCkNCg0KdHdlZXRzX3RleHQuZGYyJGNhbnRDaGFycyA8LSBuY2hhcih0d2VldHNfdGV4dC5kZjIkdGV4dCkNCmdncGxvdCh0d2VldHNfdGV4dC5kZjIsIGFlcyh4PWNhbnRDaGFycykpICsNCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM2OWIzYTIiLCBjb2xvcj0iI2U5ZWNlZiIsIGFscGhhPTAuOCkgKw0KICBnZ3RpdGxlKCJDYW50aWRhZCBkZSBjYXRhY3RlcmVzIHBvciB0d2VldCIpICsNCiAgdGhlbWVfaXBzdW0oKQ0KYGBgDQoNCiMjIyBNZW5vcyBudW1lcm9zIHkgc2ltYm9sb3MNCg0KYGBge3J9DQoNCnR3ZWV0c190ZXh0LmRmMiR0ZXh0IDwtIGdzdWIoIltbOnB1bmN0Ol1dIiwiIix0d2VldHNfdGV4dC5kZjIkdGV4dCkNCnR3ZWV0c190ZXh0LmRmMiR0ZXh0IDwtIGdzdWIoIlxcdypbMC05XStcXHcqXFxzKiIsICIiLHR3ZWV0c190ZXh0LmRmMiR0ZXh0KQ0KdHdlZXRzX3RleHQuZGYyJGNhbnRDaGFycyA8LSBuY2hhcih0d2VldHNfdGV4dC5kZjIkdGV4dCkNCmdncGxvdCh0d2VldHNfdGV4dC5kZjIsIGFlcyh4PWNhbnRDaGFycykpICsNCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM2OWIzYTIiLCBjb2xvcj0iI2U5ZWNlZiIsIGFscGhhPTAuOCkgKw0KICBnZ3RpdGxlKCJTaW4gY2FyYWN0ZXJlcyBlc3BlY2lhbGVzIHkgbnVtZXJvcyIpICsNCiAgdGhlbWVfaXBzdW0oKQ0KDQpgYGANCg0KIyBIYXNodGFncw0KDQojIyBDYW50aWRhZCBkZSBudWxvcw0KYGBge3J9DQp0d2VldHNfaGFzaGVzX251bGwgPC0gdHdlZXRzJGZpbmQoJ3siaGFzaHRhZ3MiOnsiJGVsZW1NYXRjaCI6eyIkaW4iOltudWxsXSwgIiRleGlzdHMiOnRydWV9fX0nKQ0KcHJpbnQobnJvdyh0d2VldHNfaGFzaGVzKSkNCmBgYA0KDQojIyBQcmVwcm9jZXNhbWllbnRvDQpgYGB7cn0NCnR3ZWV0c19jb3VudCA8LSBtb25nbyhkYj0nRE1VQkEnLCBjb2xsZWN0aW9uPSd0d2VldF9jb3VudF9oYXNodGFncycpDQp0d2VldHNfY291bnQgPC0gdHdlZXRzX2NvdW50JGZpbmQoKQ0KdHdlZXRzX2NvdW50JGhhc2h0YWdfMiA8LSBnc3ViKCJbWzpwdW5jdDpdXSIsIiIsdHdlZXRzX2NvdW50JGhhc2h0YWcpOw0KdHdlZXRzX2NvdW50JGhhc2h0YWdfMiA8LSBnc3ViKCJbXls6YWxudW06XVs6Ymxhbms6XT8mL1xcLV0iLCAiIiwgdHdlZXRzX2NvdW50JGhhc2h0YWdfMik7DQp0d2VldHNfY291bnQkaGFzaHRhZ18yIDwtIGljb252KHR3ZWV0c19jb3VudCRoYXNodGFnXzIsZnJvbT0iVVRGLTgiLHRvPSJBU0NJSS8vVFJBTlNMSVQiKTsNCnR3ZWV0c19jb3VudCRpc19jdWFyZW50ZW5hX3JlbGF0ZWQgPC0gRg0KZm9yIChpIGluIGN1YXJlbnRlbmFfd29yZHMpIHsNCiAgdHdlZXRzX2NvdW50JGlzX2N1YXJlbnRlbmFfcmVsYXRlZCA8LSBpZmVsc2UoZ3JlcGwoaSwgdHdlZXRzX2NvdW50JGhhc2h0YWdfMiwgZml4ZWQ9IFQpLCBULCB0d2VldHNfY291bnQkaXNfY3VhcmVudGVuYV9yZWxhdGVkKQ0KfQ0KdHdlZXRzX2NvdW50JGlzX3NleF9yZWxhdGVkIDwtIEYNCmZvciAoaSBpbiBzZXhfd29yZHMpIHsNCiAgdHdlZXRzX2NvdW50JGlzX3NleF9yZWxhdGVkIDwtIGlmZWxzZShncmVwbChpLCB0d2VldHNfY291bnQkaGFzaHRhZ18yLCBmaXhlZD0gVCksIFQsIHR3ZWV0c19jb3VudCRpc19zZXhfcmVsYXRlZCkNCn0NCmBgYA0KDQpUb3AgMjAgZGUgaGFzaHRhZ3Mgbm8gcmVsYWNpb25hZG9zIGEgY3VhcmVudGVuYQ0KYGBge3J9DQpoZWFkKHR3ZWV0c19jb3VudFshdHdlZXRzX2NvdW50JGlzX2N1YXJlbnRlbmFfcmVsYXRlZCAmICF0d2VldHNfY291bnQkaXNfc2V4X3JlbGF0ZWQsXSAlPiUgc2VsZWN0KDI6MyksIG49MjApDQoNCmBgYA0KDQoNCkFsZ28gcXVlIG1lIGxsYW1vIGxhIGF0ZW5jaW9uOiANCiogQ3ViYQ0KKiBNw6l4aWNvLCBiYXJ0bGV0dCAoTWluaXN0cm8gbWV4aWNhbm8pLCBzbnRlIChzaW5kaWNhdG8gZGUgcHJvZmVzb3JlcykuDQoqIFZlbmV6dWVsYSwgcHJvdGVjY2lvbnlhY2Npb24NCiogQUZQLCB0ZW7DrWEgdW5hIGRvYmxlIGltcGxpY2FjacOzbiBmb25kbyBkZSBwZW5zacOzbiBvIGFnZW5jaWEgZGUgcHJlbnNhIGZyYW5jZXNhLiBMYSBwcmltZXJhIGlkZWEgZGUgdW4gZm9uZG8gZGUgcGVuc2lvbmVzIHF1ZSBwdWRpZXNlIHVzYXJzZSBjb21vIGZvbmRvIGRlIGVtZXJnZW5jaWEgeSBxdWUgZ2VuZXJhYmEgcG9sw6ltaWNhIGVyYSBpbnRlcmVzYW50ZSBjb21vIHJlYWNjaW9uIGFsIGNvdmlkLiBTaW4gZW1iYXJnbyBoYWNpZW5kbyB1bmEgc2VndW5kYSBiw7pzcXVlZGEgYXBhcnRpciBkZWwgY2FtcG8gdGV4dG8sIHZlbW9zIHF1ZSB1biBoYXNodGFnIGNvbiByZXBlcmN1c2nDs24gYW1iaWd1YSwgdG9jYSBhbWJvcyB0ZW1hcyB5IGFkZW3DoXMgZm9uZG9zIGRlIHBlbnNpw7NuIGRlIG90cm9zIHBhw61zZXMuIFBvciBsbyBxdWUgZW50cmFyIGVuIGVsIHNpZ25pZmljYSBtdWNobyB0aWVtcG8geSBwb2NhIGluZm9ybWFjacOzbiBlc3BlY8OtZmljYS4gDQoNCg0KVE9ETzogDQoqIEhheSBhbGdvIGNvbiBwb3NpYmlsaWRhZCBkZSBzZXIgcHJvZnVuZGl6YWRvLCBxdWUgZXMgcG9ycXVlIGRlIGNhZGEgdW5vLCBxdWUgaW1wYWN0bywgcXVpZW5lcyBsbyBnZW5lcmFyb24sIHF1ZSBpbmZsdWVuY2lhLCBmdWVyb24gdHJlbmRpbmcgdG9waWMsIGN1YW50b3MgZMOtYXM/IA0KKiBBcmdlbnRpbmEgdnMgZWwgcmVzdG8gKEN1YmEsIE1leGljbywgQ2hpbGUpLg0KKiBUaWVuZW4gcXVlIHZlciBlc3RvcyBoYXNodGFncyBjb24gbG9zIHRyZW5kaW5nIHRvcGljPyBtaXNtbyBzaWVuZG8gcmFuZG9tLCBsbGVnYW1vcyBhIG9idGVuZXIgcGFydGUgZGUgZXNhIHJlcHJlc2VudGF0aXZpZGFkIGRlIGxvcyB0cmVuZGluZyB0b3BpY3M/DQoNCiMgUGVyZmlscyBkZSBVc3VhcmlvczoNCg0KYGBge3J9DQp1c2VyX2VzdGFkaXN0aWNhcyA8LSBtb25nbyhkYj0iRE1VQkEiLCBjb2xsZWN0aW9uPSJ1c2VyX2VzdGFkaXN0aWNhcyIpDQpzdW1tYXJ5KGluZm9fdXNlcikNCiMgVXNlciBiYXNlDQppbmZvX3VzZXIgPC0gdXNlcl9lc3RhZGlzdGljYXMkZmluZCgpDQojIENvbiBsb2cgc2luIGxvcyBxdWUgdGllbmUgMA0KZGF0YV9sb2cgPC0gYXMuZGF0YS5mcmFtZShhcHBseShpbmZvX3VzZXJbLDU6OV0sIDIsIGxvZykpDQojIExvZyBjb24gbG9zIHF1ZSB0aWVuZSAwDQppbmZvX3VzZXJbaW5mb191c2VyID09IDBdIDwtIDAuMDAwMDENCmRhdGFfbG9nXzEgPC0gYXMuZGF0YS5mcmFtZShhcHBseShpbmZvX3VzZXJbLDU6OV0sIDIsIGxvZykpDQoNCmNhdCgiQ2FudGlkYWQgZGUgdXN1YXJpb3MgcXVlIGhhbiB0d2l0dGVhZG86ICIsIG5yb3coaW5mb191c2VyKSkNCmBgYA0KDQpgYGB7cn0NCg0KIyBnZ3BhaXJzKGRhdGFfbG9nKQ0KIyBnZ3BhaXJzKGluZm9fdXNlclssMTo1XSkNCg0KYm94cGxvdChpbmZvX3VzZXJbLDU6OV0pDQoNCiMgQ29uIDAncw0KYm94cGxvdChkYXRhX2xvZykNCiMgQ29uIDAuMDAwMDAwMSdzDQpib3hwbG90KGRhdGFfbG9nXzEpDQoNCiMgDQojIGluZm9fdXNlciR2ZXJpZmljYWRvIDwtIGlmZWxzZShpbmZvX3VzZXIkdmVyaWZpZWQsICJWZXJpZmljYWRvcyIsICJTaW4gdmVyaWZpY2FyIikNCiMgaW5mb191c2VyJHZlcmlmaWNhZG8gPC0gYXMuZmFjdG9yKGluZm9fdXNlciR2ZXJpZmljYWRvKQ0KDQpgYGANCg0KVG9kbzogDQoqIEp1bnRhciB1c3VhcmlvcyBmaW5hbGVzLCB1c3VhcmlvcyBxdWUgZnVlcm9uIHJlcGxpY2Fkb3MNCiogUXVlIGhhY2UgcXVlIHVuIHVzdWFyaW8gc2VhIG3DoXMgZGl2dWxnYWRvPyBIYXkgYWxndW5hIG1lZGlkYSBkZSByZWxldmFuY2lhIGRlIHVuIHVzdWFyaW8/IEFxdWVsbG9zIG3DoXMgcG9wdWxhcmVzIChTZWd1biBxdWUgY3JpdGVyaW8/KSBzb24gZGUgcXVlIHRpcG8/IEluc3RpdHVjaW9uZXMsIHVzdWFyaW9zIGNvbXVuZXMsIGJvdHM/IFF1ZSB0YW4gYWN0aXZvcyBzb24/IEluZmx1eWUgZXNvPyBEZXNkZSBxdWUgZGlzcG9zaXRpdm8gbG8gaGFjZW4/IFF1ZSB0aXBvIGRlIHRleHRvIGNyZWFuPyBRdWUgaGFzaHRhZ3MgdXNhbj8gDQpEZSBxdWUgcmVnaW9uZXMgc29uPyBIYXkgYWxnbyBpbnRlcmVzYW50ZSBhaMOtPyBIYXkgcHJlZG9taW5pbyBkZSBhbGd1biBwYWlzPyBIYXkgcGFpc2VzIGRvbmRlIHNlIHVzYSBtw6FzIGVsIHR3aXR0ZXI/IA0KDQoNCiMgVGlwb3MgZGUgdXN1YXJpb3M6DQoNCmBgYHtyfQ0KDQp1c2VyX3R3ZWV0c19lc3RhZGlzdGljYXMgPC0gbW9uZ28oZGI9IkRNVUJBIiwgY29sbGVjdGlvbj0idXNlcl90d2VldHNfZXN0YWRpc3RpY2FzIikNCiMgVXNlciBiYXNlDQppbmZvX3VzZXIgPC0gdXNlcl90d2VldHNfZXN0YWRpc3RpY2FzJGZpbmQoKQ0Kc3VtbWFyeShpbmZvX3VzZXIkaXNfbm9uZSkNCg0KDQppbmZvX3VzZXJbaW5mb191c2VyID09IDBdIDwtIDAuMDAwMDENCmRhdGFfbG9nXzEgPC0gYXMuZGF0YS5mcmFtZShhcHBseShpbmZvX3VzZXJbLDM6N10sIDIsIGxvZykpDQojIFBsb3QgZGUgZ3J1cG9zDQoNCnBsb3Qoc29ydChkYXRhX2xvZ18xJGlzX3J0KSkNCnBsb3Qoc29ydChkYXRhX2xvZ18xJGlzX29ubHlfcnQpKQ0KcGxvdChzb3J0KGRhdGFfbG9nXzEkaXNfb25seV9xdCkpDQpwbG90KHNvcnQoZGF0YV9sb2dfMSRpc19ub25lKSkNCnBsb3Qoc29ydChkYXRhX2xvZ18xJGlzX3F0KSkNCg0KYGBgDQoNClRPRE86IEJpbm5pbmcgY29uIGVzdG8/IEFsaW5lYXIgZGlzdGludG9zIGdydXBvcyBlbiBjYWRhIGNhdGVnb3JpYT8gU29sbyBjbGFzaWZpY2FybG9zPw0KDQoNCiMjIFVzdWFyaW9zIGNvbiBtw6FzIHR3ZWV0cw0KDQpgYGB7cn0NCmhlYWQoaW5mb191c2VyW29yZGVyKGluZm9fdXNlciRjb3VudCwgZGVjcmVhc2luZyA9IFQpLF0pDQpgYGANCg0KQ3VyaW9zYW1lbnRlLCBsb3MgdXN1YXJpb3MgZmluYWxlcyBjb24gbcOhcyB0d2VldHMgc29uIGNyZWFkb3Jlcy4gc2Vyw6FuIGJvdHM/DQoNCiMjIENhdGVnb3JpemFyDQoNCmBgYHtyfQ0KaW5mb191c2VyJHRpcG8gPC0gaWZlbHNlKGluZm9fdXNlciRpc19ub25lID4gaW5mb191c2VyJGlzX29ubHlfcnQgKyBpbmZvX3VzZXIkaXNfb25seV9ydCwgIkNyZWFkb3IiLCAiRGlmdXNvciIpDQpgYGANCg0KYGBge3J9DQpiYXJwbG90KHRhYmxlKGluZm9fdXNlciR0aXBvKSkNCmluZm9fdXNlcl9ncmFmIDwtIGRhdGEuZnJhbWUodGFibGUoaW5mb191c2VyJHRpcG8pKQ0KbmFtZXMoaW5mb191c2VyX2dyYWYpIDwtIGMoIlRpcG9fdXN1YXJpbyIsICJDYW50aWRhZCIpDQoNCiMgcG5nKGZpbGVuYW1lPSJ0aXBvX3VzdWFyaW9fY3JlYWNpb24ucG5nIiwgd2lkdGg9MTAwMCwgYmc9IndoaXRlIikNCmdncGxvdChpbmZvX3VzZXJfZ3JhZiwgYWVzKHg9cmVvcmRlcihUaXBvX3VzdWFyaW8gLCBDYW50aWRhZCksIHk9Q2FudGlkYWQsIGZpbGw9VGlwb191c3VhcmlvKSkgKyANCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJTZXQyIikgKw0KICAgIGxhYnMoDQogICAgICB0aXRsZSA9ICIiLA0KICAgICAgc3VidGl0bGUgPSAiIiwNCiAgICAgIGNhcHRpb24gPSAiIiwNCiAgICAgIHRhZyA9ICIiDQogICAgICApICsNCiAgICB4bGFiKCIiKSArDQogICAgeWxhYigiIikgKw0KICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLCANCiAgICAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTQpLA0KICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KCBtYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApKSwNCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSAxMCwgciA9IDEwLCBiID0gMTAsIGwgPSAxMCkpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNCksDQogICAgIyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgDQogICAgIyAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSAxMCwgciA9IDEwLCBiID0gMTAsIGwgPSAxMCkpDQogICAgICAgICAgKSArDQogICAgY29vcmRfZmxpcCgpDQojIGRldi5vZmYoKQ0KYGBgDQoNCiMjIyBVc3VhcmlvcyBzZWfDum4gcG9wdWxhcmlkYWQNCg0KYGBge3J9DQp1c2VyX2VzdGFkaXN0aWNhcyA8LSBtb25nbyhkYj0iRE1VQkEiLCBjb2xsZWN0aW9uPSJ1c2VyX2VzdGFkaXN0aWNhcyIpDQppbmZvX3VzZXIgPC0gdXNlcl9lc3RhZGlzdGljYXMkZmluZCgpDQoNCmRhdGFfbG9nIDwtIGFzLmRhdGEuZnJhbWUoYXBwbHkoaW5mb191c2VyWyw1OjldLCAyLCBsb2cxMCkpDQppbmZvX3VzZXJbaW5mb191c2VyID09IDBdIDwtIDAuMDAwMDENCmluZm9fdXNlcltpcy5uYShpbmZvX3VzZXIpXSA8LSAwLjAwMDENCmRhdGFfbG9nXzEgPC0gYXMuZGF0YS5mcmFtZShhcHBseShpbmZvX3VzZXJbLDU6OV0sIDIsIGxvZzEwKSkNCg0KYGBgDQoNCkNvcnJlbGxhdGlvbnMNCmBgYHtyfQ0KZ2dwYWlycyhkYXRhX2xvZ18xKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmJpbl9lcV9mcmVxIDwtIGRpc2NyZXRpemUoZGF0YV9sb2dfMSRmb2xsb3dlcnNfY291bnQsImVxdWFsZnJlcSIsIDIwKQ0KYmluX2VxX2ZyZXEkZm9sbG93ZXJzX2NvdW50ID0gZGF0YV9sb2dfMSRmb2xsb3dlcnNfY291bnQNCg0KIyBQb3IgY2FkYSBiaW4gY2FsY3VsYW1vcyBsYSBtZWRpYSB5IHJlZW1wbGF6YW1vcyBlbiBlbCBhdHJpYnV0byBzdWF2aXphZG8NCmZvcihiaW4gaW4gMToyMCl7DQogIGJpbl9lcV9mcmVxJHN1YXZpemFkb1sgYmluX2VxX2ZyZXEkWD09YmluXSA9IG1lYW4oYmluX2VxX2ZyZXEkZm9sbG93ZXJzX2NvdW50WyBiaW5fZXFfZnJlcSRYPT1iaW5dKQ0KfQ0KDQojIGdyYWZpY28gU2VwYWwuV2lkdGggb3JkZW5hZG8gZGUgbWVub3IgYSBtYXlvcg0KcGxvdChzb3J0KGRhdGFfbG9nXzEkZm9sbG93ZXJzX2NvdW50KSAsIHR5cGUgPSAicCIsIGNvbD0icmVkIiwgDQogICAgIHlsYWIgPSAiZm9sbG93ZXJzX2NvdW50IiwgeGxhYiA9ICJPYnNlcnZhY2lvbmVzIiwgbWFpbiA9ICJEYXRvIG9yaWdpbmFsIHZzIHN1YXZpemFkbyIpDQojIEFncmVnbyBsYSBzZXJpZSBkZSBsYSB2YXJpYWJsZSBtZWRpYSANCmxpbmVzKHNvcnQoYmluX2VxX2ZyZXEkc3Vhdml6YWRvKSwNCiAgICAgIHR5cGUgPSAicCIsIGNvbD0iYmx1ZSIpDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQ9YygiT3JpZ2luYWwiLCAiU3Vhdml6YWRvIiksIGNvbD1jKCJyZWQiLCAiYmx1ZSIpLCBsdHk9MSkNCmBgYA0KDQpgYGB7cn0NCg0KDQpiaW5fZXFfZnJlcSA8LSBkaXNjcmV0aXplKGRhdGFfbG9nXzEkbGlzdGVkX2NvdW50LCJlcXVhbGZyZXEiLCAyMCkNCmJpbl9lcV9mcmVxJGxpc3RlZF9jb3VudCA9IGRhdGFfbG9nXzEkbGlzdGVkX2NvdW50DQoNCiMgUG9yIGNhZGEgYmluIGNhbGN1bGFtb3MgbGEgbWVkaWEgeSByZWVtcGxhemFtb3MgZW4gZWwgYXRyaWJ1dG8gc3Vhdml6YWRvDQpmb3IoYmluIGluIDE6MjApew0KICBiaW5fZXFfZnJlcSRzdWF2aXphZG9bIGJpbl9lcV9mcmVxJFg9PWJpbl0gPSBtZWFuKGJpbl9lcV9mcmVxJGxpc3RlZF9jb3VudFsgYmluX2VxX2ZyZXEkWD09YmluXSkNCn0NCg0KIyBncmFmaWNvIFNlcGFsLldpZHRoIG9yZGVuYWRvIGRlIG1lbm9yIGEgbWF5b3INCnBsb3Qoc29ydChkYXRhX2xvZ18xJGxpc3RlZF9jb3VudCkgLCB0eXBlID0gInAiLCBjb2w9InJlZCIsIA0KICAgICB5bGFiID0gImxpc3RlZF9jb3VudCIsIHhsYWIgPSAiT2JzZXJ2YWNpb25lcyIsIG1haW4gPSAiRGF0byBvcmlnaW5hbCB2cyBzdWF2aXphZG8iKQ0KIyBBZ3JlZ28gbGEgc2VyaWUgZGUgbGEgdmFyaWFibGUgbWVkaWEgDQpsaW5lcyhzb3J0KGJpbl9lcV9mcmVxJHN1YXZpemFkbyksDQogICAgICB0eXBlID0gInAiLCBjb2w9ImJsdWUiKQ0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kPWMoIk9yaWdpbmFsIiwgIlN1YXZpemFkbyIpLCBjb2w9YygicmVkIiwgImJsdWUiKSwgbHR5PTEpDQpgYGANCg0KIyMjIFVzdWFyaW9zIHNlZ8O6biBhY3RpdmlkYWQNCg0KYGBge3J9DQojIG5vX25hX2RhdGEgPC0gZGF0YV9sb2dfMVshaXMubmEoZGF0YV9sb2dfMSRzdGF0dXNlc19jb3VudCksXQ0KYmluX2VxX2ZyZXEgPC0gZGlzY3JldGl6ZShkYXRhX2xvZ18xJHN0YXR1c2VzX2NvdW50LCJlcXVhbHdpZHRoIiwgNSkNCmJpbl9lcV9mcmVxJHN0YXR1c2VzX2NvdW50ID0gZGF0YV9sb2dfMSRzdGF0dXNlc19jb3VudA0KDQojIFBvciBjYWRhIGJpbiBjYWxjdWxhbW9zIGxhIG1lZGlhIHkgcmVlbXBsYXphbW9zIGVuIGVsIGF0cmlidXRvIHN1YXZpemFkbw0KZm9yKGJpbiBpbiAxOjUpew0KICBiaW5fZXFfZnJlcSRzdWF2aXphZG9bIGJpbl9lcV9mcmVxJFg9PWJpbl0gPSBtZWFuKGJpbl9lcV9mcmVxJHN0YXR1c2VzX2NvdW50WyBiaW5fZXFfZnJlcSRYPT1iaW5dKQ0KfQ0KDQojIGdyYWZpY28gU2VwYWwuV2lkdGggb3JkZW5hZG8gZGUgbWVub3IgYSBtYXlvcg0KcGxvdChzb3J0KGRhdGFfbG9nXzEkc3RhdHVzZXNfY291bnQpICwgdHlwZSA9ICJwIiwgY29sPSJyZWQiLCANCiAgICAgeWxhYiA9ICJzdGF0dXNlc19jb3VudCIsIHhsYWIgPSAiT2JzZXJ2YWNpb25lcyIsIG1haW4gPSAiRGF0byBvcmlnaW5hbCB2cyBzdWF2aXphZG8iKQ0KIyBBZ3JlZ28gbGEgc2VyaWUgZGUgbGEgdmFyaWFibGUgbWVkaWEgDQpsaW5lcyhzb3J0KGJpbl9lcV9mcmVxJHN1YXZpemFkbyksDQogICAgICB0eXBlID0gInAiLCBjb2w9ImJsdWUiKQ0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kPWMoIk9yaWdpbmFsIiwgIlN1YXZpemFkbyIpLCBjb2w9YygicmVkIiwgImJsdWUiKSwgbHR5PTEpDQpgYGANCg0KYGBge3J9DQoNCiMgbm9fbmFfZGF0YSA8LSBkYXRhX2xvZ18xWyFpcy5uYShkYXRhX2xvZ18xJGZhdm91cml0ZXNfY291bnQpLF0NCmJpbl9lcV9mcmVxIDwtIGRpc2NyZXRpemUoZGF0YV9sb2dfMSRmYXZvdXJpdGVzX2NvdW50LCJlcXVhbHdpZHRoIiwgMTApDQpiaW5fZXFfZnJlcSRmYXZvdXJpdGVzX2NvdW50ID0gZGF0YV9sb2dfMSRmYXZvdXJpdGVzX2NvdW50DQoNCiMgUG9yIGNhZGEgYmluIGNhbGN1bGFtb3MgbGEgbWVkaWEgeSByZWVtcGxhemFtb3MgZW4gZWwgYXRyaWJ1dG8gc3Vhdml6YWRvDQpmb3IoYmluIGluIDE6MTApew0KICBiaW5fZXFfZnJlcSRzdWF2aXphZG9bIGJpbl9lcV9mcmVxJFg9PWJpbl0gPSBtZWFuKGJpbl9lcV9mcmVxJGZhdm91cml0ZXNfY291bnRbIGJpbl9lcV9mcmVxJFg9PWJpbl0pDQp9DQoNCiMgZ3JhZmljbyBTZXBhbC5XaWR0aCBvcmRlbmFkbyBkZSBtZW5vciBhIG1heW9yDQpwbG90KHNvcnQoZGF0YV9sb2dfMSRmYXZvdXJpdGVzX2NvdW50KSAsIHR5cGUgPSAicCIsIGNvbD0icmVkIiwgDQogICAgIHlsYWIgPSAiZmF2b3VyaXRlc19jb3VudCIsIHhsYWIgPSAiT2JzZXJ2YWNpb25lcyIsIG1haW4gPSAiRGF0byBvcmlnaW5hbCB2cyBzdWF2aXphZG8iKQ0KIyBBZ3JlZ28gbGEgc2VyaWUgZGUgbGEgdmFyaWFibGUgbWVkaWEgDQpsaW5lcyhzb3J0KGJpbl9lcV9mcmVxJHN1YXZpemFkbyksDQogICAgICB0eXBlID0gInAiLCBjb2w9ImJsdWUiKQ0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kPWMoIk9yaWdpbmFsIiwgIlN1YXZpemFkbyIpLCBjb2w9YygicmVkIiwgImJsdWUiKSwgbHR5PTEpDQoNCmBgYA0KDQoNCg0KVE9ETzogDQoqIERlbnRybyBkZSBsb3MgY3JlYWRvcmVzLCBhbGd1bm8gZnVlIHJldHdldGVhZG8/IENpdGFkbz8gQ3VhbCBlcyBlbCBpbXBhY3RvIGRlIGxvcyBjcmVhZG9yZXM/DQoqIERlbnRybyBkZSBsb3MgZGlmdXNvcmVzLCBxdWUgaW1wYWN0byB0aWVuZW4/IFF1ZSByZWxldmFuY2lhIHRpZW5lbiBsb3MgY3JlYWRvcmVzIG9yaWdpbmFsZXM/IEN1YW5kbyB0d2VldHMgZnVlcm9uIGFtcGxpZmljYWRvcyBtw6FzIGRlIHVuYSB2ZXogZW4gZWwgZ3J1cG8gZGUgdHdpdHRlcm9zIGZpbmFsZXM/DQoqIEVzIG11eSBzaW1wbGlzdGEgZXN0bz8gRnVuY2lvbmE/IEhheSBkaXNwb3NpdGl2b3MgcHJpdmlsZWdpYWRvcz8gVXNhbiBzb2Z0d2FyZSBwYXJhIHB1YmxpY2FjaW9uZXMgbG9zIGNyZWFkb3Jlcz8gTG9zIGRpZnVzb3Jlcz8NCiogRW50cmUgbG9zIGNyZWFkb3JlcywgaGF5IHZlcmlmaWNhZG9zPyBIYXkgYWxndW5hIGZvcm1hIGRlIGV2YWx1YXIgbGEgY29uZmlhYmlsaWRhZCBvIGxhIHZlcmFjaWRhZCBkZSBsbyBxdWUgZGljZW4/DQoqIEVudHJlIGxvcyBkaWZ1c29yZXMsIGhheSBmYWtlIG5ld3M/IEhheSBkaWZ1c2lvbiBpbmRpc2NyaW1pbmFkYT8gSGF5IHJlbGFjaW9uIGVudHJlIGFsZ3VuIHBhciBkZSB1c3Vhcmlvcz8gSGF5IGFsZ3VuYSBwZXJzb25hIHF1ZSB0aWVuZSBtw6FzIGRpZnVzaW9uIHF1ZSBvdHJhPw0Kcw0KDQoNCiMgUGFpc2VzDQoNCmBgYHtyfQ0KDQp0d2VldHMgPC0gbW9uZ28oY29sbGVjdGlvbiA9ICJ0d2VldHNfbG93ZXIiLCBkYiA9ICJETVVCQSIpDQoNCmRmX2xvY2F0aW9uIDwtIHR3ZWV0cyRhZ2dyZWdhdGUoJ1t7DQogICAgICAgICAgICAiJHByb2plY3QiOiB7IA0KICAgICAgICAgICAgICAgICJfaWQiOiAiJF9pZCIsDQogICAgICAgICAgICAgICAgImxvY2F0aW9uIjogIiRsb2NhdGlvbiIsDQogICAgICAgICAgICAgICAgInJldHdlZXRfbG9jYXRpb24iOiAiJHJldHdlZXRfbG9jYXRpb24iLA0KICAgICAgICAgICAgICAgICJxdW90ZWRfbG9jYXRpb24iOiAiJHF1b3RlZF9sb2NhdGlvbiIsDQogICAgICAgICAgICAgICAgImNvdW50cnlfY29kZSI6ICIkY291bnRyeV9jb2RlIiwNCiAgICAgICAgICAgICAgICAiY291bnRyeSI6ICIkY291bnRyeSIsDQogICAgICAgICAgICAgICAgImxhdCI6ICIkbGF0IiwNCiAgICAgICAgICAgICAgICAibG5nIjogIiRsbmciDQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICBdJykNCmBgYA0KDQpgYGB7cn0NCm5vbWJyZV9sb2NhdGlvbiA8LSBjKCJsb2NhdGlvbiIsICJyZXR3ZWV0IiwgInF1b3RlZCIsICJjb3VudHJ5X2NvZGUiLCAiY291bnRyeSIsICJsYXQiLCAibG5nIikNCmNhbnRfdW5pcXVlIDwtIGMoIGxlbmd0aCh1bmlxdWUoZGZfbG9jYXRpb24kbG9jYXRpb24pKQ0KICAgICAgICAgICAgICAgICAgLGxlbmd0aCh1bmlxdWUoZGZfbG9jYXRpb24kcmV0d2VldF9sb2NhdGlvbikpDQogICAgICAgICAgICAgICAgICAsbGVuZ3RoKHVuaXF1ZShkZl9sb2NhdGlvbiRxdW90ZWRfbG9jYXRpb24pKQ0KICAgICAgICAgICAgICAgICAgLGxlbmd0aCh1bmlxdWUoZGZfbG9jYXRpb24kY291bnRyeV9jb2RlKSkNCiAgICAgICAgICAgICAgICAgICxsZW5ndGgodW5pcXVlKGRmX2xvY2F0aW9uJGNvdW50cnkpKQ0KICAgICAgICAgICAgICAgICAgLGxlbmd0aCh1bmlxdWUoZGZfbG9jYXRpb24kbGF0KSkNCiAgICAgICAgICAgICAgICAgICxsZW5ndGgodW5pcXVlKGRmX2xvY2F0aW9uJGxuZykpKQ0KY2FudF9uYSA8LSBjKCBucm93KGRmX2xvY2F0aW9uW2lzLm5hKGRmX2xvY2F0aW9uJGxvY2F0aW9uKSxdKQ0KICAgICAgICAgICAgICAsIG5yb3coZGZfbG9jYXRpb25baXMubmEoZGZfbG9jYXRpb24kcmV0d2VldF9sb2NhdGlvbiksXSkNCiAgICAgICAgICAgICAgLCBucm93KGRmX2xvY2F0aW9uW2lzLm5hKGRmX2xvY2F0aW9uJHF1b3RlZF9sb2NhdGlvbiksXSkNCiAgICAgICAgICAgICAgLCBucm93KGRmX2xvY2F0aW9uW2lzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfY29kZSksXSkNCiAgICAgICAgICAgICAgLCBucm93KGRmX2xvY2F0aW9uW2lzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnkpLF0pDQogICAgICAgICAgICAgICwgbnJvdyhkZl9sb2NhdGlvbltpcy5uYShkZl9sb2NhdGlvbiRsYXQpLF0pDQogICAgICAgICAgICAgICwgbnJvdyhkZl9sb2NhdGlvbltpcy5uYShkZl9sb2NhdGlvbiRsbmcpLF0pDQopDQpkZiA8LSBkby5jYWxsKHJiaW5kLCBNYXAoZGF0YS5mcmFtZSwgQT1ub21icmVfbG9jYXRpb24sIEI9Y2FudF91bmlxdWUsIEM9Y2FudF9uYSkpDQpuYW1lcyhkZilbMV0gPC0gIkF0cmlidXRvIg0KbmFtZXMoZGYpWzJdIDwtICJVbmlxdWUiDQpuYW1lcyhkZilbM10gPC0gIk5hIg0KDQpkZiRwb3JjZW50YWplX25hIDwtIGRmJE5hIC8gbnJvdyhkZl9sb2NhdGlvbikgKiAxMDANCmBgYA0KDQpgYGB7cn0NCg0KcG5nKGZpbGVuYW1lPSJsb2NhdGlvbl9wb3JjX25hLnBuZyIsIHdpZHRoPTEwMDAsIGJnPSJ3aGl0ZSIpDQpnZ3Bsb3QoZGYsIGFlcyh4PXJlb3JkZXIoQXRyaWJ1dG8sIHBvcmNlbnRhamVfbmEpLCB5PXBvcmNlbnRhamVfbmEsIGZpbGw9QXRyaWJ1dG8pKSArIA0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iU2V0MiIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICIiLA0KICAgIHN1YnRpdGxlID0gIiIsDQogICAgY2FwdGlvbiA9ICIiLA0KICAgIHRhZyA9ICIiDQogICkgKw0KICB4bGFiKCIiKSArDQogIHlsYWIoIiIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIA0KICAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTQpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggbWFyZ2luID0gbWFyZ2luKDEwLCAxMCwgMTAsIDEwKSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDEwLCByID0gMTAsIGIgPSAxMCwgbCA9IDEwKSksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE0KSwNCiAgICAgICAgYXNwZWN0LnJhdGlvID0gMS8xDQogICkgKw0KICBjb29yZF9mbGlwKCkNCmRldi5vZmYoKQ0KDQpgYGANCg0KYGBge3J9DQoNCnBhaXNlc19lbiA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxMdWNhc1xcRGVza3RvcFxcMjAxOVxcRGF0YSBtaW5uaW5nXFxEYXRhTWluaW5nVWJhMjAyMFxcVHBzXFxUcDFcXGNvdW50cmllcy5lbi5jc3YiLCBoZWFkZXIgPSBULCBzZXAgPSAnOycpDQpwYWlzZXNfZXMgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcTHVjYXNcXERlc2t0b3BcXDIwMTlcXERhdGEgbWlubmluZ1xcRGF0YU1pbmluZ1ViYTIwMjBcXFRwc1xcVHAxXFxjb3VudHJpZXMuZXMuY3N2IiwgaGVhZGVyID0gVCwgc2VwID0gJzsnKQ0KDQpgYGANCg0KYGBge3J9DQoNCmhlYWQocGFpc2VzX2VuKQ0KaGVhZChwYWlzZXNfZXMpDQpwYWlzZXNfZXMkUGFpcyA8LSB0cmltd3MocGFpc2VzX2VzJFBhaXMsIHdoaWNoID0gImJvdGgiKQ0KcGFpc2VzX2VzJENvZGlnbyA8LSB0cmltd3MocGFpc2VzX2VzJENvZGlnbywgd2hpY2ggPSAiYm90aCIpDQpwYWlzZXNfZXMkUmVnaW9uIDwtIHRyaW13cyhwYWlzZXNfZXMkUmVnaW9uLCB3aGljaCA9ICJib3RoIikNCnBhaXNlc19lcyRDb250aW5lbnRlIDwtIHRyaW13cyhwYWlzZXNfZXMkQ29udGluZW50ZSwgd2hpY2ggPSAiYm90aCIpDQpkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPC0gZGZfbG9jYXRpb24kY291bnRyeQ0KZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzIgPC0gZGZfbG9jYXRpb24kY291bnRyeV9jb2RlDQoNCmBgYA0KDQpgYGB7cn0NCmZvcihpIGluIHBhaXNlc19lbiROQU1FKXsNCiAgcHJpbnQoaSkNCiAgZGZfbG9jYXRpb24kY291bnRyeV8yIDwtIGlmZWxzZShncmVwbCh0b2xvd2VyKGkpLCB0b2xvd2VyKGRmX2xvY2F0aW9uJGxvY2F0aW9uKSwgZml4ZWQ9IFQpLCB0b2xvd2VyKGkpLCBkZl9sb2NhdGlvbiRjb3VudHJ5XzIpDQp9DQoNCg0KZm9yKGkgaW4gcGFpc2VzX2VuJE5BTUUpew0KICBwcmludChpKQ0KICBpZiAobnJvdyhkZl9sb2NhdGlvblshaXMubmEoZGZfbG9jYXRpb24kY291bnRyeV8yKSAmIGRmX2xvY2F0aW9uJGNvdW50cnlfMiA9PSB0b2xvd2VyKGkpLF0pID4gMCkgew0KICAgICMgZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzJbIWlzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfMikgJiBkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPT0gdG9sb3dlcignc3BhaW4nKV0gPC0gYXMuY2hhcmFjdGVyLmZhY3RvcihwYWlzZXNfZW4kSVNPW3BhaXNlc19lbiROQU1FID09ICdTUEFJTiddKQ0KICAgICMgZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzJbIWlzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfMikgJiBkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPT0gdG9sb3dlcihpKV0gPC0gYXMuY2hhcmFjdGVyLmZhY3RvcihwYWlzZXNfZW4kSVNPW3BhaXNlc19lbiROQU1FID09IGldKQ0KICAgIGRmX2xvY2F0aW9uWyFpcy5uYShkZl9sb2NhdGlvbiRjb3VudHJ5XzIpICYgZGZfbG9jYXRpb24kY291bnRyeV8yID09IHRvbG93ZXIoaSksXSRjb3VudHJ5X2NvZGVfMiA8LSBwYWlzZXNfZW4kSVNPW3BhaXNlc19lbiROQU1FID09IGldDQogIH0NCn0NCmBgYA0KDQoNCmBgYHtyfQ0KZm9yKGkgaW4gcGFpc2VzX2VzJFBhaXMpew0KICBwcmludChpKQ0KICAjIGlmZWxzZShncmVwbCgiQXJnZW50aW5hIiwgZGZfbG9jYXRpb24kbG9jYXRpb24sIGZpeGVkPSBUKSwgIkFyZ2VudGluYSIsICIiKQ0KICBkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPC0gaWZlbHNlKGdyZXBsKHRvbG93ZXIoaSksIHRvbG93ZXIoZGZfbG9jYXRpb24kbG9jYXRpb24pLCBmaXhlZD0gVCksIHRvbG93ZXIoaSksIGRmX2xvY2F0aW9uJGNvdW50cnlfMikNCn0NCg0KZm9yKGkgaW4gcGFpc2VzX2VzJFBhaXMpew0KICBwcmludChpKQ0KICBpZiAobnJvdyhkZl9sb2NhdGlvblshaXMubmEoZGZfbG9jYXRpb24kY291bnRyeV8yKSAmIGRmX2xvY2F0aW9uJGNvdW50cnlfMiA9PSB0b2xvd2VyKGkpLF0pID4gMCkgew0KICAgICMgZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzJbIWlzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfMikgJiBkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPT0gdG9sb3dlcignc3BhaW4nKV0gPC0gYXMuY2hhcmFjdGVyLmZhY3RvcihwYWlzZXNfZW4kSVNPW3BhaXNlc19lbiROQU1FID09ICdTUEFJTiddKQ0KICAgICMgZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzJbIWlzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfMikgJiBkZl9sb2NhdGlvbiRjb3VudHJ5XzIgPT0gdG9sb3dlcihpKV0gPC0gYXMuY2hhcmFjdGVyLmZhY3RvcihwYWlzZXNfZW4kSVNPW3BhaXNlc19lbiROQU1FID09IGldKQ0KICAgIGRmX2xvY2F0aW9uWyFpcy5uYShkZl9sb2NhdGlvbiRjb3VudHJ5XzIpICYgZGZfbG9jYXRpb24kY291bnRyeV8yID09IHRvbG93ZXIoaSksXSRjb3VudHJ5X2NvZGVfMiA8LSBwYWlzZXNfZXMkQ29kaWdvW3BhaXNlc19lcyRQYWlzID09IGldDQogIH0NCiAgIyBkZl9sb2NhdGlvbiRjb3VudHJ5X2NvZGVfMlshaXMubmEoZGZfbG9jYXRpb24kY291bnRyeV8yKSAmIGRmX2xvY2F0aW9uJGNvdW50cnlfMiA9PSB0b2xvd2VyKGkpXSA8LSBhcy5jaGFyYWN0ZXIuZmFjdG9yKHBhaXNlc19lcyRDb2RpZ29bcGFpc2VzX2VzJFBhaXMgPT0gaV0pDQp9DQpgYGANCg0KI1VuaW1vcyBjb250aW5lbnRlDQpgYGB7cn0NCg0KZm9yKGkgaW4gcGFpc2VzX2VzJENvZGlnbyl7DQogIHByaW50KGkpDQogIGRmX2xvY2F0aW9uJFJlZ2lvblshaXMubmEoZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzIpICYgZGZfbG9jYXRpb24kY291bnRyeV9jb2RlXzIgPT0gaV0gPC0gcGFpc2VzX2VzJFJlZ2lvbltwYWlzZXNfZXMkQ29kaWdvID09IGldDQogIGRmX2xvY2F0aW9uJENvbnRpbmVudGVbIWlzLm5hKGRmX2xvY2F0aW9uJGNvdW50cnlfY29kZV8yKSAmIGRmX2xvY2F0aW9uJGNvdW50cnlfY29kZV8yID09IGldIDwtIHBhaXNlc19lcyRDb250aW5lbnRlW3BhaXNlc19lcyRDb2RpZ28gPT0gaV0NCn0NCmBgYA0KDQpgYGB7cn0NCg0KDQphdXggPC0gZGF0YS5mcmFtZSh0YWJsZShkZl9sb2NhdGlvbiRDb250aW5lbnRlKSkNCm5hbWVzKGF1eCkgPC0gYygiQ29udGluZW50ZSIsICJGcmVjdWVuY2lhIikNCmF1eA0KcG5nKGZpbGVuYW1lPSJsb2NhdGlvbl9wb3JjX25hLnBuZyIsIHdpZHRoPTEwMDAsIGJnPSJ3aGl0ZSIpDQogIGdncGxvdChhdXgsIGFlcyh4PXJlb3JkZXIoQ29udGluZW50ZSwgRnJlY3VlbmNpYSksIHk9RnJlY3VlbmNpYSwgZmlsbD1Db250aW5lbnRlKSkgKyANCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJTZXQyIikgKw0KICAgIGxhYnMoDQogICAgICB0aXRsZSA9ICIiLA0KICAgICAgc3VidGl0bGUgPSAiIiwNCiAgICAgIGNhcHRpb24gPSAiIiwNCiAgICAgIHRhZyA9ICIiDQogICAgKSArDQogICAgeGxhYigiIikgKw0KICAgIHlsYWIoIiIpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgDQogICAgICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE0KSwNCiAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggbWFyZ2luID0gbWFyZ2luKDEwLCAxMCwgMTAsIDEwKSksDQogICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMTAsIHIgPSAxMCwgYiA9IDEwLCBsID0gMTApKSwNCiAgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNCksDQogICAgICAgICAgYXNwZWN0LnJhdGlvID0gMS8xDQogICAgKSArDQogICAgY29vcmRfZmxpcCgpDQpkZXYub2ZmKCkNCmBgYA0KDQoNCiMjIENsYXNpZmljYXIgZW4gbm90aWNpYXMgLSBwb2xpdGljYSAtIG90cm9zDQoNCmBgYHtyfQ0KDQp0IDwtIG1vbmdvKGNvbGxlY3Rpb24gPSAidHdlZXRzX2xvd2VyIiwgZGIgPSAiRE1VQkEiKQ0KYXV4IDwtIHQkYWdncmVnYXRlKCdbeyIkcHJvamVjdCI6eyJfaWQiOiAiJF9pZCIsInVzZXJfaWQiOiIkdXNlcl9pZCIsInNjcmVlbl9uYW1lIjoiJHNjcmVlbl9uYW1lIiwidGV4dCI6IiRkZXNjcmlwdGlvbiJ9fV0nKQ0KYGBgDQoNCmBgYHtyfQ0KYXV4JHRleHQgPC0gdG9sb3dlcihhdXgkdGV4dCkNCmF1eCR0ZXh0IDwtIGdzdWIoImh0dHAuKiIsIiIsYXV4JHRleHQpDQphdXgkdGV4dCA8LSBnc3ViKCJodHRwcy4qIiwiIixhdXgkdGV4dCkNCg0KIyAjUXVpdGFuZG8gbG9zIGhhc2h0YWdzIHkgdXN1YXJpb3MgZW4gbG9zIHR3ZWV0c190ZXh0DQojIGF1eCR0ZXh0IDwtIGdzdWIoIiNcXHcrIiwiIixhdXgkdGV4dCkNCmF1eCR0ZXh0IDwtIGdzdWIoIkBcXHcrIiwiIixhdXgkdGV4dCkNCg0KYXV4JHRleHQgPC0gZ3N1YigiW1s6cHVuY3Q6XV0iLCIiLGF1eCR0ZXh0KQ0KYXV4JHRleHQgPC0gZ3N1YigiXFx3KlswLTldK1xcdypcXHMqIiwgIiIsYXV4JHRleHQpDQoNCmF1eCR0ZXh0IDwtIGdzdWIoIltbOnB1bmN0Ol1dIiwiIixhdXgkdGV4dCkNCmF1eCR0ZXh0IDwtIGdzdWIoIlteWzphbG51bTpdWzpibGFuazpdPyYvXFwtXSIsICIiLCBhdXgkdGV4dCkNCmF1eCR0ZXh0IDwtIGljb252KGF1eCR0ZXh0LGZyb209IlVURi04Iix0bz0iQVNDSUkvL1RSQU5TTElUIikNCiAgDQpwYWxhYnJhc19ub3RpY2lhcyA8LSBjKCJub3RpY2lhIiwgInBlcmlvZGlzbW8iLCAicGVyaW9kaXN0YSIsICdwZXJpb2RpY28nLCAibmV3cyIsICdqb3VybmFsaXN0JywgInJlcG9ydGVybyIsICJwcm9ncmFtYSBkZSB0diIsICd0ZWxldmlzaW9uJywgJ1JldXRlcnMgJywgJ2VscGFpc2FtZXJpY2EnLCAncHJvZHVjdG9yYScsICdjb25kdWN0b3InLCAnY29sdW1uaXN0YScsICdjb3JyZXNwb25zYWwnLCAndGVsZXN1cicpDQphdXgkaXNfbmV3c19yZWxhdGVkIDwtIEYNCmZvciAoaSBpbiBwYWxhYnJhc19ub3RpY2lhcykgew0KICBhdXgkaXNfbmV3c19yZWxhdGVkIDwtIGlmZWxzZShncmVwbChpLCBhdXgkdGV4dCwgZml4ZWQ9IFQpLCBULCBhdXgkaXNfbmV3c19yZWxhdGVkKQ0KfQ0KcGFsYWJyYXNfcG9saXRpY2EgPC0gYygicG9saXRpY28iLCAic2VuYWRvciIsICJkaXB1dGFkbyIsICJhbGNhbGRlIiwgInN1YnNlY3JldGFyaW8iLCAic2VjcmV0YXJpbyIsICJzZWNyZXRhcmlhIiwgInByZXNpZGVuY2lhIiwgInByZXNpZGVudGUiLCAibWluaXN0ZXJpbyIsICJtaW5pc3RybyIsICJtaW5pc3RyYSIsICJww7pibGljbyIsICJwdWJsaWNvIiwgImNhbmNpbGxlciIsICJQYXJ0aWRvIFNvY2lhbGlzdGEiLCAiUFNVViIsICJwYXJ0aWRvIGRlbCBwdWVibG8iLCAnYXNhbWJsZWEgbmFjaW9uYWwnKQ0KYXV4JGlzX3BvbGl0aWNfcmVsYXRlZCA8LSBGDQpmb3IgKGkgaW4gcGFsYWJyYXNfcG9saXRpY2EpIHsNCiAgYXV4JGlzX3BvbGl0aWNfcmVsYXRlZCA8LSBpZmVsc2UoZ3JlcGwoaSwgYXV4JHRleHQsIGZpeGVkPSBUKSwgVCwgYXV4JGlzX3BvbGl0aWNfcmVsYXRlZCkNCn0NCmBgYA0KDQpgYGB7cn0NCiMgYmFycGxvdCh0d2VldHMkaXNfbmV3c19yZWxhdGVkKQ0KIyBiYXJwbG90KHR3ZWV0cyRpc19wb2xpdGljX3JlbGF0ZWQpDQpgYGANCg0KYGBge3J9DQphdXgkdGlwb191c2VyID0gIk5vcm1hbCINCmF1eFthdXgkaXNfbmV3c19yZWxhdGVkLF0kdGlwb191c2VyIDwtICJNZWRpbyINCmF1eFthdXgkaXNfcG9saXRpY19yZWxhdGVkLF0kdGlwb191c2VyIDwtICJQb2xpdGljYSINCmF1eCRpc19uZXdzX3JlbGF0ZWQgPC0gTlVMTA0KYXV4JGlzX3BvbGl0aWNfcmVsYXRlZCA8LSBOVUxMDQphdXgkdGV4dCA8LSBOVUxMDQoNCmF1eFthdXgkdGlwb191c2VyPT0nUG9saXRpY2EnLF0NCiMgdHdlZXRzIDwtIG1lcmdlKHR3ZWV0cywgYXV4LCBieT0idHdlZXRfaWQiKQ0KYXV4ICU+JSBncm91cF9ieShzY3JlZW5fbmFtZSkgJT4lIHN1bW1hcmlzZSh0aXBvID0gbWF4KHRpcG9fdXNlcikpDQojIHRhYmxlKGF1eCR0aXBvX3VzZXIpDQpgYGANCg0KDQpgYGB7cn0NCnVzZXIgPC0gYXV4ICU+JSBzZWxlY3QoJ19pZCcsICd1c2VyX2lkJywgJ3NjcmVlbl9uYW1lJywgJ3RpcG9fdXNlcicpDQpgYGANCg0KDQoNCmBgYHtyfQ0KYXV4IDwtIHQkYWdncmVnYXRlKCdbeyIkcHJvamVjdCI6eyJfaWQiOiIkX2lkIiwidXNlcl9pZCI6IiRyZXR3ZWV0X3VzZXJfaWQiLCJzY3JlZW5fbmFtZSI6IiRyZXR3ZWV0X3NjcmVlbl9uYW1lIiwidGV4dCI6IiRyZXR3ZWV0X2Rlc2NyaXB0aW9uIn19XScpDQphdXggPC0gYXV4WyFpcy5uYShhdXgkc2NyZWVuX25hbWUpLF0NCmBgYA0KDQpgYGB7cn0NCmF1eCR0ZXh0IDwtIHRvbG93ZXIoYXV4JHRleHQpDQphdXgkdGV4dCA8LSBnc3ViKCJodHRwLioiLCIiLGF1eCR0ZXh0KQ0KYXV4JHRleHQgPC0gZ3N1YigiaHR0cHMuKiIsIiIsYXV4JHRleHQpDQoNCiMgI1F1aXRhbmRvIGxvcyBoYXNodGFncyB5IHVzdWFyaW9zIGVuIGxvcyB0d2VldHNfdGV4dA0KIyBhdXgkdGV4dCA8LSBnc3ViKCIjXFx3KyIsIiIsYXV4JHRleHQpDQphdXgkdGV4dCA8LSBnc3ViKCJAXFx3KyIsIiIsYXV4JHRleHQpDQoNCmF1eCR0ZXh0IDwtIGdzdWIoIltbOnB1bmN0Ol1dIiwiIixhdXgkdGV4dCkNCmF1eCR0ZXh0IDwtIGdzdWIoIlxcdypbMC05XStcXHcqXFxzKiIsICIiLGF1eCR0ZXh0KQ0KDQphdXgkdGV4dCA8LSBnc3ViKCJbWzpwdW5jdDpdXSIsIiIsYXV4JHRleHQpDQphdXgkdGV4dCA8LSBnc3ViKCJbXls6YWxudW06XVs6Ymxhbms6XT8mL1xcLV0iLCAiIiwgYXV4JHRleHQpDQphdXgkdGV4dCA8LSBpY29udihhdXgkdGV4dCxmcm9tPSJVVEYtOCIsdG89IkFTQ0lJLy9UUkFOU0xJVCIpDQogIA0KcGFsYWJyYXNfbm90aWNpYXMgPC0gYygibm90aWNpYSIsICJwZXJpb2Rpc21vIiwgInBlcmlvZGlzdGEiLCAncGVyaW9kaWNvJywgIm5ld3MiLCAnam91cm5hbGlzdCcsICJyZXBvcnRlcm8iLCAicHJvZ3JhbWEgZGUgdHYiLCAndGVsZXZpc2lvbicsICdSZXV0ZXJzICcsICdlbHBhaXNhbWVyaWNhJywgJ3Byb2R1Y3RvcmEnLCAnY29uZHVjdG9yJywgJ2NvbHVtbmlzdGEnLCAnY29ycmVzcG9uc2FsJywgJ3RlbGVzdXInKQ0KYXV4JGlzX25ld3NfcmVsYXRlZCA8LSBGDQpmb3IgKGkgaW4gcGFsYWJyYXNfbm90aWNpYXMpIHsNCiAgYXV4JGlzX25ld3NfcmVsYXRlZCA8LSBpZmVsc2UoZ3JlcGwoaSwgYXV4JHRleHQsIGZpeGVkPSBUKSwgVCwgYXV4JGlzX25ld3NfcmVsYXRlZCkNCn0NCnBhbGFicmFzX3BvbGl0aWNhIDwtIGMoInBvbGl0aWNvIiwgInNlbmFkb3IiLCAiZGlwdXRhZG8iLCAiYWxjYWxkZSIsICJzdWJzZWNyZXRhcmlvIiwgInNlY3JldGFyaW8iLCAic2VjcmV0YXJpYSIsICJwcmVzaWRlbmNpYSIsICJwcmVzaWRlbnRlIiwgIm1pbmlzdGVyaW8iLCAibWluaXN0cm8iLCAibWluaXN0cmEiLCAicMO6YmxpY28iLCAicHVibGljbyIsICJjYW5jaWxsZXIiLCAiUGFydGlkbyBTb2NpYWxpc3RhIiwgIlBTVVYiLCAicGFydGlkbyBkZWwgcHVlYmxvIiwgJ2FzYW1ibGVhIG5hY2lvbmFsJykNCmF1eCRpc19wb2xpdGljX3JlbGF0ZWQgPC0gRg0KZm9yIChpIGluIHBhbGFicmFzX3BvbGl0aWNhKSB7DQogIGF1eCRpc19wb2xpdGljX3JlbGF0ZWQgPC0gaWZlbHNlKGdyZXBsKGksIGF1eCR0ZXh0LCBmaXhlZD0gVCksIFQsIGF1eCRpc19wb2xpdGljX3JlbGF0ZWQpDQp9DQpgYGANCg0KYGBge3J9DQojIGJhcnBsb3QodHdlZXRzJGlzX25ld3NfcmVsYXRlZCkNCiMgYmFycGxvdCh0d2VldHMkaXNfcG9saXRpY19yZWxhdGVkKQ0KYGBgDQoNCmBgYHtyfQ0KYXV4JHRpcG9fdXNlciA9ICJOb3JtYWwiDQphdXhbYXV4JGlzX25ld3NfcmVsYXRlZCxdJHRpcG9fdXNlciA8LSAiTWVkaW8iDQphdXhbYXV4JGlzX3BvbGl0aWNfcmVsYXRlZCxdJHRpcG9fdXNlciA8LSAiUG9saXRpY2EiDQphdXgkaXNfbmV3c19yZWxhdGVkIDwtIE5VTEwNCmF1eCRpc19wb2xpdGljX3JlbGF0ZWQgPC0gTlVMTA0KYXV4JHRleHQgPC0gTlVMTA0KDQphdXhbYXV4JHRpcG9fdXNlcj09J1BvbGl0aWNhJyxdDQojIHR3ZWV0cyA8LSBtZXJnZSh0d2VldHMsIGF1eCwgYnk9InR3ZWV0X2lkIikNCmF1eCAlPiUgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JSBzdW1tYXJpc2UodGlwbyA9IG1heCh0aXBvX3VzZXIpKQ0KIyB0YWJsZShhdXgkdGlwb191c2VyKQ0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KbmFtZXModXNlcikgPC0gYygiX2lkIiwgInVzZXJfaWQiLCAic2NyZWVuX25hbWUiLCAidGlwb191c2VyIikNCm5hbWVzKGF1eCkgPC0gYygiX2lkIiwgInVzZXJfaWQiLCAic2NyZWVuX25hbWUiLCAidGlwb191c2VyIikNCnVzZXIgPC0gcmJpbmQodXNlciwgYXV4KQ0KYGBgDQoNCg0KDQoNCg==